Сериализация объектов в Go (Golang): JSON, XML, Gob и Protocol Buffers

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

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

Начать курс

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

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

1. Встроенный пакет encoding/json

Самый популярный способ сериализации в Go. JSON — человекочитаемый, кросс-платформенный формат. Пакет encoding/json предоставляет функции Marshal и Unmarshal.

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"}

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

    // Десериализация
    var decoded User
    err = json.Unmarshal(jsonData, &decoded)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%+v\n", decoded)
}

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

  • Поддержка тегов структуры для настройки имён полей.
  • Работает со срезами, картами, вложенными структурами.
  • Медленнее бинарных форматов, но удобен для отладки.
  • Не поддерживает циклические ссылки.

2. encoding/xml — XML сериализация

XML используется в SOAP, RSS, конфигурационных файлах. Пакет encoding/xml работает аналогично JSON, но с тегами xml.

type Book struct {
    Title  string `xml:"title"`
    Author string `xml:"author"`
    Pages  int    `xml:"pages,attr"`
}

func main() {
    book := Book{Title: "Go in Action", Author: "William Kennedy", Pages: 500}
    xmlData, _ := xml.MarshalIndent(book, "", "  ")
    fmt.Println(string(xmlData))
    // <Book pages="500">
    //   <title>Go in Action</title>
    //   <author>William Kennedy</author>
    // </Book>
}

Когда использовать:

  • Интеграция с legacy системами.
  • Строгие схемы (XSD).
  • Документоориентированные данные.

3. encoding/gob — нативный бинарный формат Go

Пакет encoding/gob создан специально для Go. Он эффективно кодирует данные в бинарный формат, поддерживает сложные типы (интерфейсы, каналы, функции — с ограничениями).

import "encoding/gob"

type Task struct {
    ID     int
    Status string
}

func main() {
    var network bytes.Buffer
    enc := gob.NewEncoder(&network)
    dec := gob.NewDecoder(&network)

    task := Task{ID: 42, Status: "done"}
    err := enc.Encode(task)
    if err != nil {
        log.Fatal(err)
    }

    var restored Task
    err = dec.Decode(&restored)
    fmt.Println(restored) // {42 done}
}

Преимущества:

  • Высокая скорость и компактность.
  • Автоматическая регистрация типов.
  • Поддержка циклических структур.

Недостаток: несовместимость с другими языками.

4. Protocol Buffers (protobuf) — быстрая бинарная сериализация

Разработан Google. Требует определения схемы в .proto файле и генерации кода через protoc. Библиотека google.golang.org/protobuf — современный стандарт.

// user.proto
// syntax = "proto3";
// message User {
//   int32 id = 1;
//   string name = 2;
//   string email = 3;
// }

// Сгенерированный код: user.pb.go

func main() {
    user := &pb.User{Id: 1, Name: "Bob", Email: "bob@test.com"}
    data, _ := proto.Marshal(user)
    fmt.Println(len(data)) // ~15 байт

    var restored pb.User
    proto.Unmarshal(data, &restored)
    fmt.Println(restored.GetName())
}
                
    
    

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