Как указать значения по умолчанию при разборе 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