カスタム Struct に自前で Unmarshal を実装して json -> object に decode するときに無限ループを引き起こして panic しないようにするTipsです。
サンプルケースですが、以下のコードは json を decodeす るときに panic を引き起こします。
type Person struct { Name string `json:"name"` Age int64 `json:"age"` } func (p *Person) UnmarshalJSON(data []byte) error { if p.Age == 0 { p.Age = 10 } return json.Unmarshal(data, p) }
refs: https://play.golang.org/p/7RtVampOalT
理由は json を decode する対象の Person struct に対して再帰的に UnmarshalJSON をかけてしまい無限ループに陥ってしまうからです。
こう言ったケースでは UnmarshalJSON メソッド内で別の type として Alias を切ることで無限ループを回避できます。
func (p *Person) UnmarshalJSON(data []byte) error { if p.Age == 0 { p.Age = 10 } type Alias Person pp := &struct { *Alias }{ Alias: (*Alias)(p), } return json.Unmarshal(data, pp) }
ref: https://play.golang.org/p/lymBTGoMbB5
元ネタはこちらの記事です↓