Ответ
В Go сериализация (преобразование данных в формат для хранения или передачи) и десериализация (обратный процесс) обычно выполняются с помощью стандартных пакетов encoding/json, encoding/xml, encoding/gob или encoding/binary.
JSON (наиболее популярный вариант):
Используется пакет encoding/json.
package main
import (
"encoding/json"
"fmt"
"log"
)
type Person struct {
Name string `json:"name"` // Тег для кастомизации имени поля в JSON
Age int `json:"age"`
// Поля должны быть экспортируемыми (начинаться с заглавной буквы)
}
func main() {
// Сериализация (Marshal): Go-структура -> JSON-байты
person1 := Person{"Alice", 30}
jsonData, err := json.Marshal(person1)
if err != nil {
log.Fatalf("Ошибка сериализации: %v", err)
}
fmt.Printf("JSON данные: %sn", string(jsonData)) // JSON данные: {"name":"Alice","age":30}
// Для красивого вывода JSON (с отступами)
prettyJSONData, err := json.MarshalIndent(person1, "", " ")
if err != nil {
log.Fatalf("Ошибка сериализации с отступами: %v", err)
}
fmt.Printf("Красивый JSON:n%sn", string(prettyJSONData))
// Десериализация (Unmarshal): JSON-байты -> Go-структура
var person2 Person
err = json.Unmarshal(jsonData, &person2)
if err != nil {
log.Fatalf("Ошибка десериализации: %v", err)
}
fmt.Printf("Десериализованная структура: %+vn", person2) // Десериализованная структура: {Name:Alice Age:30}
}
XML и Gob:
Работают аналогично, используя пакеты encoding/xml и encoding/gob соответственно. encoding/gob часто используется для передачи данных между Go-программами.
Protobuf:
Для высокопроизводительной и кросс-языковой сериализации часто используется Protocol Buffers (github.com/golang/protobuf или google.golang.org/protobuf). Требует определения схемы данных.
Бинарная сериализация:
Пакет encoding/binary позволяет читать и записывать данные в бинарном формате, что полезно для низкоуровневых протоколов или работы с файлами.
Важные нюансы:
- Экспортируемые поля: Для сериализации/десериализации поля структуры должны быть экспортируемыми (начинаться с заглавной буквы).
- Теги: Теги, такие как
json:"name", позволяют управлять именами полей в сериализованном формате, пропускать поля (json:"-") или делать их опциональными (json:"name,omitempty"). - Обработка ошибок: Всегда проверяйте возвращаемое значение
errпосле операций сериализации/десериализации. - Потоковая обработка: Для работы с большими объемами данных используйте
json.Encoderиjson.Decoderсio.Readerиio.Writerдля потоковой обработки без загрузки всего содержимого в память.
Ответ 18+ 🔞
Давай разберём эту тему про сериализацию в Go, а то тут, блядь, как в огороде бузина, а в Киеве дядька. Всё вроде просто, но есть нюансы, ёпта.
JSON — наш главный по тарелочкам
Чаще всего юзают encoding/json. Работает, как швейцарские часы, если не накосячить.
package main
import (
"encoding/json"
"fmt"
"log"
)
type Person struct {
Name string `json:"name"` // Смотри, теги! Это чтобы JSON не орал "а где name?"
Age int `json:"age"`
// Важный момент, ёпта: поля должны быть с большой буквы! Иначе json их в упор не видит.
}
func main() {
// Сериализация (Marshal): Из нашей структуры делаем JSON-байты
person1 := Person{"Alice", 30}
jsonData, err := json.Marshal(person1)
if err != nil {
log.Fatalf("Ошибка сериализации: %v", err) // Всегда проверяй ошибку, а то потом волнение ебать
}
fmt.Printf("JSON данные: %sn", string(jsonData)) // Выведет: {"name":"Alice","age":30}
// А если хочется красиво, с отступами, как для важной персоны
prettyJSONData, err := json.MarshalIndent(person1, "", " ")
if err != nil {
log.Fatalf("Ошибка сериализации с отступами: %v", err)
}
fmt.Printf("Красивый JSON:n%sn", string(prettyJSONData))
// Десериализация (Unmarshal): Из JSON-байтов собираем обратно структуру
var person2 Person
err = json.Unmarshal(jsonData, &person2) // Не забудь амперсанд, а то нихуя не запишется!
if err != nil {
log.Fatalf("Ошибка десериализации: %v", err)
}
fmt.Printf("Десериализованная структура: %+vn", person2) // {Name:Alice Age:30}
}
XML, Gob и прочая шушера
- XML — через
encoding/xml. Тот же принцип, только теги другие. Для любителей старой школы. - Gob (
encoding/gob) — это наш, гоферский, внутренний формат. Супер-пупер для общения между двумя Go-программами. Быстро и без лишних телодвижений. - Protobuf — это уже серьёзная артиллерия. Для максимальной производительности и когда надо общаться с питоном или жабой. Требует отдельной схемы, но оно того стоит, если данные овердохуища.
Бинарная сериализация
encoding/binary — это когда тебе нужно вручную, побитово, как в старые добрые. Для своих протоколов или чтения/записи специфичных файлов. Сильно, но и головной боли можно наебаться.
Важные нюансы, на которых все обжигаются:
- Экспортируемые поля, блядь! Поля в структуре должны быть с большой буквы (
Name,Age). Иначеjson.Marshalпосмотрит на них, как баран на новые ворота, и проигнорирует. Тишина в JSON-файле будет. - Теги — твои лучшие друзья.
json:"name"— говорит, как поле назвать в JSON.json:"-"— чтобы нахрен его выкинуть.json:"name,omitempty"— чтобы не светить пустое поле. Учи матчасть! - Ошибки, ёпта!
err— это святое. Всегда проверяй послеMarshalиUnmarshal. Иначе потом будешь искать, почему данные — хуй с горы, а не то, что ожидал. - Для больших данных — потоки. Если данных дохуя, не грузи всё в память. Используй
json.NewEncoder(writer)иjson.NewDecoder(reader). Они будут кушать данные по кусочкам, как мартышлюшка банан.
Вот и вся магия. Главное — не выёбывайся с бинарными форматами, если можно обойтись JSON. И проверяй ошибки, а то сам от себя охуеешь потом.