8 вопросов
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)Теги: 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 { ... }Тип реализует 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
}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)MessagePack - бинарный формат, схема как JSON, но компактнее и быстрее. В Go: vmihailenco/msgpack. Используют для кеша и RPC. Другие: CBOR (binary JSON), Avro (схема, стриминг). Выбор по размеру, скорости и совместимости. Для межсервисного обмена часто JSON или protobuf; MessagePack - когда нужна компактность и скорость без строгой схемы.
data, _ := msgpack.Marshal(v)
var x T
msgpack.Unmarshal(data, &x)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)
}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)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)