Как указать значения по умолчанию при разборе JSON в Go
Я хочу проанализировать объект JSON в Go, но хочу указать значения по умолчанию для полей, которые не заданы. Например, у меня есть тип структуры:
type Test struct {
A string
B string
C string
}
Значения по умолчанию для A, B и C являются соответственно "a", "b" и "c". Это означает, что когда я разбираю json:
{"A": "1", "C": 3}
Я хочу получить структуру:
Test{A: "1", B: "b", C: "3"}
Возможно ли это с помощью встроенного пакета encoding/json
? В противном случае, есть ли библиотека Go, которая имеет эту функциональность?
Ответы
Ответ 1
Это возможно с помощью encoding/json: при вызове json.Unmarshal
вам не нужно указывать пустую структуру, вы можете присвоить ей значение со значениями по умолчанию.
В вашем примере:
var example []byte = []byte(`{"A": "1", "C": "3"}`)
out := Test{
A: "default a",
B: "default b",
// default for C will be "", the empty value for a string
}
err := json.Unmarshal(example, &out) // <--
if err != nil {
panic(err)
}
fmt.Printf("%+v", out)
Запуск этого примера на игровой площадке Go возвращает {A:1 B:default b C:3}
.
Как вы можете видеть, json.Unmarshal(example, &out)
отключает JSON в out
, перезаписывая значения, указанные в JSON, но оставляя остальные поля неизменными.
Ответ 2
В случае, если у вас есть список или карта структур Test
, принятый ответ больше невозможен, но его можно легко расширить с помощью метода UnmarshalJSON:
func (t *Test) UnmarshalJSON(data []byte) error {
type testAlias Test
test := &testAlias{
B: "default B",
}
_ = json.Unmarshal(data, test)
*t = Test(*test)
return nil
}
TestAlias необходимо для предотвращения рекурсивных вызовов UnmarshalJSON. Это работает, потому что новый тип не имеет определенных методов.
https://play.golang.org/p/qiGyjRbNHg