В .NET сериализация — это богатая, во многом «магическая» библиотечная экосистема: System.Text.Json с атрибутами, конвертерами и source generators, исторический Newtonsoft.Json с его гибкостью, XmlSerializer, DataContractSerializer, давно опальный BinaryFormatter. Вы привыкли украшать классы атрибутами и доверять рантайму остальное — он сам разберётся с регистром имён, полиморфизмом и циклами.
В Go подход иной и предсказуемо более «спартанский». JSON живёт прямо в стандартной библиотеке (encoding/json), управляется не атрибутами, а тегами структур, и принципиально работает только с экспортируемыми полями. YAML в stdlib отсутствует — берётся внешняя библиотека, ровно как в .NET вы тянете YamlDotNet из NuGet. Бинарная сериализация распадается на два разных мира: «родной» для Go формат encoding/gob (только Go↔Go) и кросс-языковой Protobuf через кодогенерацию. Этот раздел перенастраивает вашу «атрибутную» интуицию на «теговую» модель Go, разбирает подводные камни (omitempty, числа в any, nil-слайсы) и показывает, где какой формат уместен.
После этого раздела вы будете:
- Уверенно работать с
encoding/json:Marshal/Unmarshal, теги, потоковыеEncoder/Decoder, и понимать, почему сериализуются только экспортируемые поля. - Знать все нюансы тегов:
omitemptyи его ловушки, новыйomitzero(Go 1.24), опциюstring, пропуск через-, и когда нужны указатели для «опциональных» полей. - Реализовывать кастомную сериализацию через
json.Marshaler/Unmarshalerиencoding.TextMarshaler(время, деньги, перечисления). - Парсить сложные конфиги в YAML через
yaml.v3, понимать строгий разбор (KnownFields) и знать про архивациюgo-yamlи канонический форк. - Осознанно выбирать между
gob, Protobuf и JSON по осям «скорость / размер / кросс-язычность / схема». - Точно сопоставлять
System.Text.JsonиNewtonsoft.Jsonсencoding/json: атрибуты против тегов, регистронезависимый матчинг против точного, роль рефлексии и source generators.
- JSON (
encoding/json) —Marshal/Unmarshal, теги иomitempty/omitzero,nullи нулевые значения, кастомные маршалеры,RawMessage, потоковыеDecoder/Encoder, производительность. Ключевая глава раздела. - YAML —
yaml.v3(не из stdlib!), теги, разбор вложенных конфигов, якоря, строгий режимKnownFields; когда YAML, а когда JSON. - Бинарные форматы: gob и Protobuf —
encoding/gobдля Go↔Go (RPC, кэш, снапшоты), Protobuf для кросс-язычности и эволюции схемы, сравнительная таблица. - Сравнение с .NET — консолидированный мостик:
System.Text.Json/Newtonsoft.Jsonпротивencoding/json, полиморфизм, перформанс, «как сделать привычное X».
Держите таблицу под рукой при чтении раздела. Детали каждого сопоставления разбираются в соответствующих главах.
| В .NET / C# | В Go | Ключевое отличие |
|---|---|---|
System.Text.Json (JsonSerializer) |
encoding/json (stdlib) |
В Go это часть стандартной библиотеки, единственный «дефолт» |
Newtonsoft.Json (Json.NET) |
encoding/json + при нужде сторонние (json-iterator, sonic) |
В Go нет «гибкого тяжеловеса» в stdlib; гибкость — через интерфейсы |
[JsonPropertyName("x")] |
тег json:"x" |
Атрибут типа → строковый тег поля |
[JsonIgnore] |
тег json:"-" |
— |
JsonIgnoreCondition.WhenWritingDefault/Null |
omitempty / omitzero (Go 1.24) |
Две разные опции с разной семантикой «пустоты» |
JsonConverter<T> |
json.Marshaler / json.Unmarshaler |
Контракт реализует сам тип, а не внешний конвертер |
[JsonDerivedType] / $type (полиморфизм) |
нет из коробки; вручную через RawMessage + дискриминатор |
В Go полиморфную (де)сериализацию пишут руками |
Utf8JsonReader/Writer, JsonSerializer source-gen |
json.Decoder/Encoder (стримы); кодоген — отдельно (Раздел 7) |
Стримы есть; компайл-тайм генерация JSON — не в stdlib |
YamlDotNet (NuGet) |
go.yaml.in/yaml/v3 (бывш. gopkg.in/yaml.v3) |
В обоих мирах YAML — внешняя зависимость |
BinaryFormatter (устарел, небезопасен) |
encoding/gob |
gob — безопасная Go-only замена идее «бинарь между своими» |
Protobuf (Google.Protobuf + protoc) |
Protobuf (google.golang.org/protobuf + protoc-gen-go) |
Формат и схема одинаковы; различается только тулинг кодогенерации |