πŸ“Š ЭффСктивная Ρ€Π°Π±ΠΎΡ‚Π° с JSON Π² Go

Π’ ΡΡ‚Π°Ρ‚ΡŒΠ΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ основныС ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Ρ‹ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с JSON Π² языкС Go. Π‘ΠΎΠ»ΡŒΡˆΠΎΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡƒΠ΄Π΅Π»Π΅Π½ΠΎ опрСдСлСниям ΠΈΠ· Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌ.

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² JSON

JSON (JavaScript Object Notation) – это Π»Π΅Π³ΠΊΠΈΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, основанный Π½Π° синтаксисС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² JavaScript. Он ΡˆΠΈΡ€ΠΎΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром Π² сСтСвых прилоТСниях.

JSON прСдставляСт Π΄Π°Π½Π½Ρ‹Π΅ Π² Π²ΠΈΠ΄Π΅ ΠΏΠ°Ρ€ Β«ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅Β» ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ массивы, числа, строки, логичСскиС значСния ΠΈ null. Он обСспСчиваСт простоту чтСния ΠΈ записи для людСй, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π»Π΅Π³ΠΊΠΎΡΡ‚ΡŒ Ρ€Π°Π·Π±ΠΎΡ€Π° ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ для ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ΠΎΠ².

Π§Ρ‚Π΅Π½ΠΈΠ΅ JSON

ДСсСриализация (Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ JSON) – это процСсс прСобразования Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° JSON Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Go. Для этих Ρ†Π΅Π»Π΅ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠ°ΠΊΠ΅Ρ‚ encoding/json, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ языка. Основная функция для чтСния Unmarshal считываСт JSON-Π΄Π°Π½Π½Ρ‹Π΅ ΠΈ сохраняСт Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ заданная пСрСмСнная. Если ΠΆΠ΅ ΠΎΠ½Π° прСдставляСт собой nil ΠΈΠ»ΠΈ Π½Π΅ являСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ, Ρ‚ΠΎ функция Π²Π΅Ρ€Π½Π΅Ρ‚ InvalidUnmarshalError.

ΠžΠ±Ρ‰Π°Ρ сигнатура: func Unmarshal(data []byte, v any) error

Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Unmarshal Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

type Worker struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
	Job  string `json:"job"`
}

func main() {
	var worker Worker
	jsonData := `{"name":"ΠŸΠ΅Ρ‚Ρ", "age":18, "job":"Backend-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ"}`
	err := json.Unmarshal([]byte(jsonData), &worker)
	if err != nil {
		fmt.Println("Ошибка чтСния JSON-Π΄Π°Π½Π½Ρ‹Ρ…:", err)
	}
	fmt.Println(worker)
}

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½ΠΎ "{ΠŸΠ΅Ρ‚Ρ 18 программист}".

  • Ѐункция Unmarshal ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ интСрСсной ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ – ΠΎΠ½Π° считываСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ поля, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠ°ΠΌ. Π’Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· большого JSON-Ρ„Π°ΠΉΠ»Π°.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ поля Name ΠΈ Age, Π° Job останСтся ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ. Π’Ρ‹Π²ΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ: "{Витя 20 }".

type Worker struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
	Job  string `json:"job"`
}
...
var worker Worker
jsonData := `{"name":"Витя", "age": 20, "city":"Москва"}`
err := json.Unmarshal([]byte(jsonData), &worker)
πŸ‘¨β€πŸ’» Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°
Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°Β»
🧩 Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ Go
Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎ Go для ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ GoΒ»
πŸŽ“ Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go для собСса
ΠŸΠΎΠ΄Ρ‚ΡΠ½ΡƒΡ‚ΡŒ свои знания ΠΏΠΎ Go Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go для собСса»

Π—Π°ΠΏΠΈΡΡŒ JSON

БСриализация (запись JSON) – это процСсс прСобразования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΏΠΎ сСти. Для этого Π² Go ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ функция Marshal() ΠΈΠ· Ρ€Π°Π½Π΅Π΅ рассмотрСнного ΠΏΠ°ΠΊΠ΅Ρ‚Π° encoding/json. Она Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π΄Π²Π° значСния – срСз Π±Π°ΠΉΡ‚ ΠΈ ΠΎΡˆΠΈΠ±ΠΊΡƒ.

Π•Ρ‘ сигнатура ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²ΠΈΠ΄: func Marshal(v any) ([]byte, error)

type Worker struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
	Job  string `json:"job"`
}

func main() {
	workerInfo := Worker{Name: "Ваня", Age: 14, Job: "Go-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ"}
	jsonInfo, err := json.Marshal(workerInfo)
	if err != nil {
		fmt.Println("Ошибка записи Π΄Π°Π½Π½Ρ‹Ρ…:", err)
	}
	fmt.Println(jsonInfo)
}

Π‘Ρ‚ΠΎΠΈΡ‚ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ записаны ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ структуры Π΄Π°Π½Π½Ρ‹Ρ…, прСдставимыС Π² Π²ΠΈΠ΄Π΅ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° JSON.

  • Для ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠΈ Ρ‚ΠΈΠΏΠ° map ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΈΠ΄ map[string]T, Π³Π΄Π΅ T – любой Ρ‚ΠΈΠΏ, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠΌ encoding/json.
  • ЦикличСскиС структуры Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠΎΠ³ΡƒΡ‚ привСсти ΠΊ попаданию Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Marshal Π² бСсконСчный Ρ†ΠΈΠΊΠ», поэтому Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ для прСобразования.
  • Для кодирования ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΈΡ… Π² Π²ΠΈΠ΄Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½ΠΈ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚. Π’ случаС nil-ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ это Π±ΡƒΠ΄Π΅Ρ‚ nil.
  • Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠ°Π½Π°Π»Ρ‹ ΠΈ Ρ‚ΠΈΠΏ complex Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ.

ΠŸΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹Π΅ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊΠΈ ΠΈ Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ€Ρ‹

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡΡ‹ Reader ΠΈ Writer

Π’ Go ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π΄Π²Π° основных интСрфСйса ΠΈΠ· ΠΏΠ°ΠΊΠ΅Ρ‚Π° io стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, io.Reader ΠΈ io.Writer. Они ΡˆΠΈΡ€ΠΎΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для Π²Π²ΠΎΠ΄Π°/Π²Ρ‹Π²ΠΎΠ΄Π° Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ, сСтСвыми соСдинСниями ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΌΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния ΠΈ записи.

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ io.Reader опрСдСляСт ΠΌΠ΅Ρ‚ΠΎΠ΄ Read, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π±ΡƒΡ„Π΅Ρ€ для чтСния, Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ количСство Π±Π°ΠΉΡ‚, ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π½Ρ‹Ρ… ΠΈΠ· источника, ΠΈ ΠΎΡˆΠΈΠ±ΠΊΡƒ. ΠŸΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… io.Reader Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ io.EOF (ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π°).

type Reader interface {
	Read(p []byte) (n int, err error)
}

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ io.Writer опрСдСляСт ΠΌΠ΅Ρ‚ΠΎΠ΄ Write, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π±ΡƒΡ„Π΅Ρ€ для записи Π΄Π°Π½Π½Ρ‹Ρ…, Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ количСство Π±Π°ΠΉΡ‚, записанных Π² Ρ†Π΅Π»Π΅Π²ΠΎΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΈ ΠΎΡˆΠΈΠ±ΠΊΡƒ.

type Writer interface {
	Write(p []byte) (n int, err error)
}

ΠŸΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ собствСнныС интСрфСйсы Reader ΠΈ Writer, Ρ€ΡƒΠΊΠΎΠ²ΠΎΠ΄ΡΡ‚Π²ΡƒΡΡΡŒ соглашСниями языка.

ΠšΠΎΠ΄ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ json.Encoder

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° json.Encoder ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для кодирования JSON-Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΈΡ… ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ записи Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Writer.

Π’Π°ΠΊ выглядит сигнатура Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для создания ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊΠ°: func NewEncoder(w io.Writer) *Encoder

type Shape struct {
	Type   string `json:"name"`
	Width  int    `json:"width"`
	Height int    `json:"height"`
}

func main() {
	// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ слайса структур Workers с Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ
	shapes := []Shape{
		{Type: "ΠšΠ²Π°Π΄Ρ€Π°Ρ‚", Width: 10, Height: 10},
		{Type: "ΠŸΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ", Width: 50, Height: 20},
	}

	var buf bytes.Buffer
	encoder := json.NewEncoder(&buf)

	// Π—Π°ΠΏΠΈΡΡŒ JSON-Π΄Π°Π½Π½Ρ‹Ρ… Π² Π±ΡƒΡ„Π΅Ρ€
	if err := encoder.Encode(shapes); err != nil {
		fmt.Println("Ошибка ΠΏΡ€ΠΈ записи JSON-Π΄Π°Π½Π½Ρ‹Ρ…:", err)
		return
	}
	fmt.Println(buf.String())
}

Π”Π΅ΠΊΠΎΠ΄Π΅Ρ€ json.Decoder

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° json.Decoder позволяСт Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ JSON ΠΈΠ· интСрфСйса Reader. К ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, ΠΈΠ· Ρ„Π°ΠΉΠ»Π°, Π±ΡƒΡ„Π΅Ρ€Π° ΠΈΠ»ΠΈ сСтСвого соСдинСния. Decoder Ρ‚Π°ΠΊΠΆΠ΅ обСспСчиваСт Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ контроля синтаксичСских ошибок ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ° JSON-Π΄Π°Π½Π½Ρ‹Ρ… Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

Π‘ΠΈΠ³Π½Π°Ρ‚ΡƒΡ€Π° для создания Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ€Π°: func NewDecoder(r io.Reader) *Decoder

Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

type Student struct {
	Name  string `json:"name"`
	Grade int    `json:"grade"`
}

func main() {
	jsonData := `{"name":"Иван", "grade":10}`

	// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±ΡƒΡ„Π΅Ρ€Π° с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ JSON
	reader := strings.NewReader(jsonData)

	// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Decoder для чтСния ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π°
	decoder := json.NewDecoder(reader)

	var student Student

	// Π§Ρ‚Π΅Π½ΠΈΠ΅ JSON ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π° ΠΈ ΠΈΡ… запись Π² student
	if err := decoder.Decode(&student); err != nil {
		fmt.Println("Ошибка дСкодирования:", err)
		return
	}

	fmt.Println(student.Name, student.Grade)
}

На экран Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½ΠΎ: Иван 10

Π’ΠΈΠΏ NullString

Π’ Go Π΅ΡΡ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ NullString для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с пустыми ΠΈΠ»ΠΈ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ значСниями JSON-Π΄Π°Π½Π½Ρ‹Ρ…. Он позволяСт явно ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, являСтся Π»ΠΈ строка пустой ΠΈΠ»ΠΈ Π½ΡƒΠ»Π΅Π²ΠΎΠΉ.

Бтандартная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go Π½Π΅ прСдоставляСт встроСнного Ρ‚ΠΈΠΏΠ° NullString, Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ структуру ΠΈΠ»ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° строку.

type NullString struct {
  String string
  Valid  bool
}

Π’ΠΈΠΏ NullString Ρ‚Π°ΠΊΠΆΠ΅ Π±Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π΅Π½ для дСсСриализации JSON-Π΄Π°Π½Π½Ρ‹Ρ… Π² нСстандартном Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅. Π‘ Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ собствСнныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ Unmarshal.

Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° создадим кастомный дСсСриализатор с использованиСм NullString.

type NullString struct {
	String string
	Valid  bool
}

func (nstr *NullString) UnmarshalCustomData(jsonData []byte) error {
	// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π»ΠΈ JSON-Π΄Π°Π½Π½Ρ‹Π΅ Π½ΡƒΠ»Π΅Π²ΠΎΠΉ строкой
	if string(jsonData) == "null" {
		nstr.Valid = false
		return nil
	}

	var s string

	// ДСсСриализация JSON
	if err := json.Unmarshal(jsonData, &s); err != nil {
		return err
	}

	// ΠŸΡ€ΠΈΡΠ²ΠΎΠ΅Π½ΠΈΠ΅ строки Ρ‚ΠΈΠΏΡƒ NullString
	nstr.String = s
	nstr.Valid = true
	return nil
}

Π”Π΅ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ нСизвСстных Π΄Π°Π½Π½Ρ‹Ρ…

Π—Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ Π² JSON хранятся Π΄Π°Π½Π½Ρ‹Π΅ Ρ€Π°Π·Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ. Π’ этом случаС ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΌΠΎΡ‡ΡŒ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² интСрфСйс ΠΈ ΠΈΡ… ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠ΅Ρ€Π΅Π±ΠΎΡ€ с использованиСм switch-case. Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ позволяСт ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ прСимущСства бСзопасности Ρ‚ΠΈΠΏΠΎΠ².

Для Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ понимания рассмотрим ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€.

func main() {
	jsonData := []byte(`{"name":"Ваня","grade":11,"classmates":["ΠŸΠ΅Ρ‚Ρ", "Π˜Π³ΠΎΡ€ΡŒ","Π“Π»Π΅Π±"]}`)

	// ДСсСриализация JSON-Π΄Π°Π½Π½Ρ‹Ρ…
	var data interface{}
	if err := json.Unmarshal(jsonData, &data); err != nil {
		fmt.Println("Ошибка ΠΏΡ€ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ JSON:", err)
	}

	// Type assertion
	res := data.(map[string]interface{})

	// ΠŸΠ΅Ρ€Π΅Π±ΠΎΡ€ ΠΊΠ»ΡŽΡ‡Π΅ΠΉ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ
	for key, val := range res {
		switch value := val.(type) {
		case string:
			fmt.Println(key, "ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ string - ", value)
		case float64:
			fmt.Println(key, "ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ float64 - ", value)
		case []interface{}:
			fmt.Println(key, "ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ []interface{} - ", value)
		default:
			fmt.Println("Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ элСмСнта нСизвСстно")
		}
	}
}

Π’Ρ‹Π²ΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ:

name ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ string -  Ваня
grade ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ float64 -  11
classmates ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ []interface{} -  [ΠŸΠ΅Ρ‚Ρ Π˜Π³ΠΎΡ€ΡŒ Π“Π»Π΅Π±]

ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹ ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
23 ноября 2018

Go vs Python: ΠΈΠ·ΡƒΡ‡Π΅Π½ΠΈΠ΅ основ языка Go Π² сравнСнии с Python

Π­Ρ‚ΠΎ Π½Π΅ сорСвнованиС Π΄Π²ΡƒΡ… языков, Π° просто Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ способ обучСния. Рассмат...
admin
19 сСнтября 2018

TOП-3 языка программирования, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹ΡƒΡ‡ΠΈΡ‚ΡŒ Π΄ΠΎ 2019

Π­Ρ‚ΠΎ Π½Π΅ просто Ρ‚Ρ€ΠΈ Π»ΡƒΡ‡ΡˆΠΈΡ… языка программирования, Π° Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ смыслС ΠΏΠΎΠΏΡ‹Ρ‚...
Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
27 октября 2017

30 Π»ΡƒΡ‡ΡˆΠΈΡ… ΠΊΠ½ΠΈΠ³ для освоСния языка программирования Go

Π˜Ρ‰Π΅Ρ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΏΠΎ Go? ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΠ΅ΠΌ 30 книг для освоСния языка программирования...