Перейти до основного вмісту
Модуль 8 · Урок 5 із 540/50 у курсі~14 min
Модульні уроки (5/5)

`кодування/json`

encoding/json — це канонічний пакет для серіалізації структур Go у JSON і назад. Знаючи його умовності та підводні камені, ви заощаджуєте години налагодження API та конфігураційних файлів.

Маршал і Немаршал

Дві основні функції:

Go
data, err := json.Marshal(v)      // Go → []byte JSON
err = json.Unmarshal(data, &v)    // JSON → Go (pass a pointer!)
Go
type User struct {
    Name  string
    Email string
}

u := User{Name: "Ada", Email: "ada@example.com"}
b, _ := json.Marshal(u)
fmt.Println(string(b))
// {"Name":"Ada","Email":"ada@example.com"}

var back User
_ = json.Unmarshal(b, &back)

Для виводу з відступом (читається людиною) використовуйте json.MarshalIndent(v, "", " ").

Лише експортовані поля

json.Marshal серіалізує лише експортовані поля (Великий регістр). Приватні поля ігноруються мовчки:

Go
type U struct {
    Name string // exported → serialized
    age  int    // private → ignored
}

Теги структури: керування назвою та параметрами

Теги json:"..." керують іменем, пропуском і типами виводу:

Go
type User struct {
    Name    string `json:"name"`                    // rename
    Email   string `json:"email,omitempty"`         // omit if zero value
    Private string `json:"-"`                       // never serialized
    ID      int    `json:"id,string"`               // number as string
}

Найбільш використовувані варіанти:

  • ,omitempty — пропускає поле, якщо воно є нульовим значенням (0, "", нуль, порожній фрагмент/карта).
  • ,- — ніколи не серіалізується/десеріалізується.
  • ,string — обертає числа/bools як рядки (корисно для ідентифікаторів JS).

Декодер/Кодер для потоків

Під час роботи з io.Reader/io.Writer (тіло HTTP, великі файли) використовуйте Decoder та Encoder замість завантаження всього в пам’ять:

Go
dec := json.NewDecoder(resp.Body)
var users []User
if err := dec.Decode(&users); err != nil {
    return err
}

enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", "  ")
_ = enc.Encode(users)

Decoder також підтримує dec.Token() для потокового аналізу по частинах і dec.DisallowUnknownFields() для відхилення JSON із неочікуваними ключами (корисно для перевірки введення).

Загальні карти та any

Якщо ви не знаєте схему, десеріалізуйте в map[string]any:

Go
var v map[string]any
_ = json.Unmarshal(data, &v)
fmt.Println(v["name"])

Значення матимуть динамічні типи (string, float64 для чисел, []any, map[string]any, bool, nil).

Поширені помилки

  • Забути &: json.Unmarshal(data, v) нічого не заповнює; вам потрібен &v.
  • Декодування структур із нульовими полями: щоб уникнути паніки, перевірте err ПЕРЕД читанням полів.
  • Несумісні типи: десеріалізація числа в рядок або навпаки повертає *json.UnmarshalTypeError.

вправи

вправи#go.m8.l5.e1
Спроби: 0Завантаження…

Серіалізуйте структуру u в JSON за допомогою json.Marshal і надрукуйте результат у вигляді рядка.

Завантаження редактора…

Рішення доступне після 3 спроб

вправи#go.m8.l5.e2
Спроби: 0Завантаження…

Десеріалізуйте `{"Name":"Ada"}` у структуру U за допомогою json.Unmarshal і надрукуйте його.

Завантаження редактора…

Рішення доступне після 3 спроб

Quiz#go.m8.l5.e3
Готовий

Чи включено поле `name string` (нижній регістр) структури до json.Marshal?

Go
type U struct {
  name string
}
b, _ := json.Marshal(U{name: "Ada"})
fmt.Println(string(b))
Варіанти відповідей