JSON обработка в Go (Golang): полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

JSON обработка в Go (Golang): полное руководство

Go (Golang) — это современный компилируемый язык программирования, разработанный в Google. Одной из его сильных сторон является встроенная поддержка формата JSON через стандартный пакет encoding/json. В отличие от многих других языков, где требуется установка сторонних библиотек, в Go обработка JSON доступна "из коробки" и отличается высокой производительностью и строгой типизацией.

В этой статье мы подробно разберём все аспекты работы с JSON в Go: от простого парсинга до сложных сценариев с пользовательскими типами и потоковой обработкой.

Основы: кодирование и декодирование JSON

Пакет encoding/json предоставляет две основные функции: json.Marshal() для сериализации Go-структур в JSON и json.Unmarshal() для десериализации JSON обратно в структуры.

Пример: сериализация структуры в JSON

package main

import (
    "encoding/json"
    "fmt"
)

type User struct {
    Name  string `json:"name"`
    Age   int    `json:"age"`
    Email string `json:"email,omitempty"`
}

func main() {
    user := User{
        Name:  "Иван Петров",
        Age:   30,
        Email: "ivan@example.com",
    }

    jsonData, err := json.Marshal(user)
    if err != nil {
        fmt.Println("Ошибка сериализации:", err)
        return
    }

    fmt.Println(string(jsonData))
    // Вывод: {"name":"Иван Петров","age":30,"email":"ivan@example.com"}
}

Пример: десериализация JSON в структуру

func main() {
    jsonString := `{"name":"Анна Смирнова","age":25,"email":"anna@example.com"}`
    
    var user User
    err := json.Unmarshal([]byte(jsonString), &user)
    if err != nil {
        fmt.Println("Ошибка десериализации:", err)
        return
    }

    fmt.Printf("Имя: %s, Возраст: %d, Email: %s\n", user.Name, user.Age, user.Email)
}

Теги структур (Struct Tags)

Теги структур в Go позволяют управлять тем, как поля будут сериализоваться в JSON. Это мощный механизм для настройки имён полей, пропуска пустых значений и других опций.

Основные опции тегов:

  • json:"name" — задаёт имя поля в JSON
  • json:"-" — полностью исключает поле из JSON
  • json:"name,omitempty" — пропускает поле, если оно содержит нулевое значение (0, "", false, nil)
  • json:"name,string" — принудительно преобразует числовое поле в строку

Пример с различными тегами:

type Product struct {
    ID          int     `json:"id"`
    Title       string  `json:"title"`
    Description string  `json:"description,omitempty"`
    Price       float64 `json:"price,string"`
    SecretKey   string  `json:"-"`
}

func main() {
    product := Product{
        ID:          101,
        Title:       "Ноутбук",
        Description: "",
        Price:       899.99,
        SecretKey:   "sk-12345",
    }

    jsonData, _ := json.MarshalIndent(product, "", "  ")
    fmt.Println(string(jsonData))
    // Вывод:
    // {
    //   "id": 101,
    //   "title": "Ноутбук",
    //   "price": "899.99"
    // }
}

Работа с произвольными JSON-данными (interface{})

Иногда структура JSON-данных заранее неизвестна. В таких случаях можно использовать тип interface{} или map[string]interface{}.

func main() {
    jsonString := `{"name":"Тест","values":[1,2,3],"active":true,"metadata":{"version":2}}`
    
    var data map[string]interface{}
    err := json.Unmarshal([]byte(jsonString), &data)
    if err != nil {
        fmt.Println("Ошибка:", err)
        return
    }

    // Доступ к значениям с приведением типов
    name := data["name"].(string)
    values := data["values"].([]interface{})
    active := data["active"].(bool)
    metadata := data["metadata"].(map[string]interface{})
    version := metadata["version"].(float64) // JSON числа всегда float64

    fmt.Printf("Имя: %s, Активен: %t, Версия: %.0f\n", name, active, version)
    
    for i, v := range values {
        fmt.Printf("Значение %d: %v\n", i, v)
    }
}

Потоковая обработка JSON

Для работы с большими JSON-файлами или потоками данных Go предоставляет json.Decoder и json.Encoder. Они позволяют обрабатывать данные без загрузки всего содержимого в память.

Чтение JSON из файла

Рекомендаций