Сериализация объектов в Go (Golang): Полное руководство

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

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

Начать курс

Сериализация объектов в Go (Golang): от JSON до Protobuf

Сериализация (маршалинг) — это процесс преобразования структуры данных (объекта) в последовательность байт для передачи по сети или сохранения на диск. Обратный процесс — десериализация (анмаршалинг). В Go эта задача решается стандартными и сторонними пакетами. Рассмотрим основные подходы.

1. Стандартная библиотека: encoding/json

Самый популярный способ. Для сериализации используется пакет encoding/json.

Базовый пример

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

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

func main() {
    user := User{ID: 1, Name: "Alice", Email: "alice@example.com"}

    // Сериализация (Marshal)
    jsonData, err := json.Marshal(user)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(jsonData)) // {"id":1,"name":"Alice","email":"alice@example.com"}

    // Десериализация (Unmarshal)
    var decoded User
    err = json.Unmarshal(jsonData, &decoded)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%+v\n", decoded) // {ID:1 Name:Alice Email:alice@example.com}
}

Важные теги структур

  • json:"field_name" — задаёт имя поля в JSON
  • ,omitempty — пропускает поле, если оно пустое (например, пустая строка, 0, nil)
  • ,string — форсирует строковое представление для числовых полей
  • - — игнорирует поле при сериализации

2. Сериализация в XML: encoding/xml

Пакет encoding/xml работает по схожему принципу, но использует XML-теги.

package main

import (
    "encoding/xml"
    "fmt"
)

type Person struct {
    XMLName xml.Name `xml:"person"`
    Name    string   `xml:"name"`
    Age     int      `xml:"age,attr"`
}

func main() {
    p := Person{Name: "Bob", Age: 30}
    xmlData, _ := xml.MarshalIndent(p, "", "  ")
    fmt.Println(string(xmlData))
    // Вывод:
    // <person age="30">
    //   <name>Bob</name>
    // </person>
}

Поддерживаются атрибуты (,attr), вложенные элементы, CDATA и пространства имён.

3. Бинарная сериализация: encoding/gob

Пакет gob — это собственный формат Go для бинарной сериализации. Идеально подходит для обмена данными между Go-приложениями.

package main

import (
    "bytes"
    "encoding/gob"
    "fmt"
    "log"
)

type Data struct {
    X, Y int
    Label string
}

func main() {
    var buf bytes.Buffer
    enc := gob.NewEncoder(&buf)
    data := Data{X: 10, Y: 20, Label: "test"}

    // Кодирование
    if err := enc.Encode(data); err != nil {
        log.Fatal(err)
    }

    // Декодирование
    var decoded Data
    dec := gob.NewDecoder(&buf)
    if err := dec.Decode(&decoded); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%+v\n", decoded) // {X:10 Y:20 Label:test}
}

Особенности gob:

  • Требует предварительной регистрации типов (если используются интерфейсы)
  • Компактнее JSON для бинарных данных
  • Не поддерживается другими языками (только Go)

4. Protocol Buffers (protobuf)

Протокол Google для эффективной бинарной сериализации. Требует установки protoc и плагина protoc-gen-go.

Шаг 1: Определение схемы (user.proto)

syntax = "proto3";
package main;

message User {
  int32 id = 1;
  string name = 2;
  string email = 3;
}

Шаг 2: Генерация кода

protoc --go_out=. user.proto

Шаг 3: Использование в Go

package main

import (
    "fmt"
    "log"
    "google.golang.org/protobuf/proto"
)

func main() {
    user := &User{
        Id:    1,
        Name:  "Charlie                    

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