Ответ
В Go для работы с JSON, как правило, используют два основных подхода:
-
Структуры (
struct) с тегами полей (рекомендуемый способ)Это идиоматичный и наиболее предпочтительный способ для работы с JSON, структура которого заранее известна. Он обеспечивает типобезопасность и прозрачность кода.
import "encoding/json" type Person struct { Name string `json:"name"` Age int `json:"age,omitempty"` // omitempty - не включать в JSON, если значение нулевое Skills []string `json:"skills"` }Для кодирования (Go -> JSON) и декодирования (JSON -> Go) используются функции
json.Marshalиjson.Unmarshalиз стандартной библиотекиencoding/json. -
Карта
map[string]interface{}Этот способ используется, когда структура JSON заранее неизвестна, или она очень динамична. Он похож на работу с JSON в скриптовых языках.
var data map[string]interface{} jsonData := []byte(`{"name":"Alice","age":25}`) json.Unmarshal(jsonData, &data) // data["name"] будет равно "Alice"Недостаток: Теряется типобезопасность. Для доступа к значениям требуются приведения типов (
data["age"].(float64)), что может привести к панике во время выполнения, если тип окажется другим.
Ответ 18+ 🔞
А, слушай, про JSON в Go? Ну, тут всё просто, как три копейки, но есть нюансы, блядь. В основном два пути, и один из них — это как идти в магазин за хлебом, а другой — как пытаться объяснить бабушке, что такое интернет.
Первый способ — по-взрослому, с структурами. Это когда ты заранее знаешь, какая тебе херня прилетит. Типобезопасно, красиво, все довольны. Заводишь себе структуру, как костюмчик по фигуре, и навешиваешь на поля теги эти, json:"как_там_в_джейсоне".
import "encoding/json"
type Person struct {
Name string `json:"name"`
Age int `json:"age,omitempty"` // omitempty — гениальная штука, чтоб не светить нули, если их нет
Skills []string `json:"skills"`
}
Дальше просто: json.Marshal — чтобы свою структуру в JSON превратить, json.Unmarshal — чтобы входящий JSON обратно в структуру запихнуть. Всё чётко, всё предсказуемо. Рекомендуемый способ, ёпта. Как по рельсам.
А второй способ — это уже для отчаянных, когда структура JSON неизвестна или меняется, как погода в Питере. Берёшь map[string]interface{} — это такая универсальная свалка, куда можно запихнуть что угодно.
var data map[string]interface{}
jsonData := []byte(`{"name":"Alice","age":25}`)
json.Unmarshal(jsonData, &data)
// Ну и потом data["name"] будет "Alice", да.
Но вот тут, блядь, подвох: типобезопасность накрывается медным тазом. Чтобы достать age, тебе надо делать приведение типа: data["age"].(float64). И если ты ошибёшься с типом — получишь панику во время выполнения, прям как обоссаться со смеху, когда не надо. Овердохуища риска, если не уверен.
Так что, если можешь — всегда используй структуры. Это надёжнее. А map[string]interface{} — это уже для крайних случаев, когда JSON приходит такой, что сам его создатель, пизда, уже не помнит, что там внутри.