Go: Сериализация

8 вопросов

1 encoding/json в Go. Маршалинг и анмаршалинг.

json.Marshal(v) - структура в JSON; json.Unmarshal(data, &v) - JSON в структуру. Теги json:"name" задают имя поля; omitempty не выводит нулевые значения. Вложенные структуры, срезы, мапы поддерживаются. Ошибки при несовпадении типов. Для потоковой обработки json.Decoder/Encoder.

type User struct {
    ID   int    // json:"id"
    Name string // json:"name,omitempty"
}
data, _ := json.Marshal(user)
var u User
json.Unmarshal(data, &u)
Открыть отдельно →
2 JSON-теги и кастомная сериализация в Go.

Теги: json:"fieldname", omitempty, - (игнор). Кастомная сериализация: реализовать json.Marshaler и json.Unmarshaler (методы с указателем на тип). Для типа Time часто оборачивают в свой тип с нужным форматом. Для сложных правил можно использовать интерфейсы и type switch при unmarshal.

func (t Time) MarshalJSON() ([]byte, error) {
    return json.Marshal(t.Format(time.RFC3339))
}
func (t *Time) UnmarshalJSON(data []byte) error { ... }
Открыть отдельно →
3 Кастомный Marshal/Unmarshal в Go.

Тип реализует json.Marshaler (MarshalJSON() ([]byte, error)) и/или json.Unmarshaler (UnmarshalJSON([]byte) error). Тогда json.Marshal/Unmarshal вызывают эти методы. Используют для нестандартного формата (например, число как строка), оберток над time.Time, enum. В UnmarshalJSON нужно разобрать []byte и присвоить полям; при ошибке вернуть json.UnmarshalTypeError или свою ошибку.

func (e *Enum) UnmarshalJSON(data []byte) error {
    var s string
    if err := json.Unmarshal(data, &s); err != nil { return err }
    switch s {
    case "a": *e = EnumA
    default: return fmt.Errorf("invalid enum")
    }
    return nil
}
Открыть отдельно →
4 Protocol Buffers в Go. Сравнение с JSON.

Protobuf - бинарный формат, схема в .proto; код генерируется (protoc --go_out). Меньше размер, быстрее парсинг; типизация и версионирование. В Go: сообщения как структуры с методами Marshal/Unmarshal; для gRPC - сгенерированные типы и клиент/сервер. JSON удобнее для отладки и API для браузеров; protobuf - для внутренних сервисов и потоков.

import "google.golang.org/protobuf/proto"
data, _ := proto.Marshal(msg)
proto.Unmarshal(data, &msg)
Открыть отдельно →
5 MessagePack и другие форматы в Go.

MessagePack - бинарный формат, схема как JSON, но компактнее и быстрее. В Go: vmihailenco/msgpack. Используют для кеша и RPC. Другие: CBOR (binary JSON), Avro (схема, стриминг). Выбор по размеру, скорости и совместимости. Для межсервисного обмена часто JSON или protobuf; MessagePack - когда нужна компактность и скорость без строгой схемы.

data, _ := msgpack.Marshal(v)
var x T
msgpack.Unmarshal(data, &x)
Открыть отдельно →
6 json.RawMessage в Go. Зачем нужен.

json.RawMessage - это []byte; при Unmarshal в него сохраняются сырые байты JSON без разбора. Удобно для отложенного парсинга или для полей с динамической структурой (например, payload события). При Marshal RawMessage выводится как вложенный JSON. Используют в обертках над событиями и в API с гибким телом.

type Event struct {
    Type string          // json:"type"
    Data json.RawMessage // json:"data"
}
var e Event
json.Unmarshal(input, &e)
switch e.Type {
case "user": var u User; json.Unmarshal(e.Data, &u)
}
Открыть отдельно →
7 CBOR и Avro в Go.

CBOR - Concise Binary Object Representation, похож на JSON, бинарный. В Go: fxamacker/cbor. Avro - формат с схемой, популярен в Kafka (Schema Registry). В Go для Avro: confluentinc/confluent-kafka-go с Avro serializer. Выбор: CBOR для компактности и простоты; Avro для стриминга с эволюцией схемы и Kafka.

// CBOR
data, _ := cbor.Marshal(v)
cbor.Unmarshal(data, &v)
Открыть отдельно →
8 YAML и XML в Go. Пакеты и использование.

YAML: gopkg.in/yaml.v3 или gopkg.in/yaml.v2 - Unmarshal/Marshal аналогично JSON, теги yaml. Используют для конфигов (Kubernetes манифесты). XML: encoding/xml - Unmarshal/Marshal с тегами xml. Используют для интеграций и legacy. Оба поддерживают структуры, вложенность, теги. Внимание к безопасности при разборе XML (XXE - отключить внешние сущности).

import "gopkg.in/yaml.v3"
var cfg Config
yaml.Unmarshal(data, &cfg)
import "encoding/xml"
xml.Unmarshal(data, &v)
Открыть отдельно →
🧠Квиз 🏆Лидеры 🎯Собесед. 📖Вопросы 📚База зн.