Сериализация объектов в 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()) }Также в библиотеке
gRPC для JavaScript (Node.js): библиотеки, настройка и примеры кода
Clikt: Мощный CLI фреймворк для Kotlin с декларативным синтаксисом
Работа с CSV в Rust: библиотека csv и практические примеры
Криптография в TypeScript: шифрование и хеширование
Symfony/EventDispatcher для PHP: полное руководство с примерами
Рекомендаций