はじめに
goでstructをJSONにしたい時には enccoding/json
を使う。埋め込みを含んだsturctのencodeの結果が埋め込まれたフィールドがstructであるかinterfaceであるかで変わる。気づかなかったので忘れないようにメモ。
例
以下のような Person
structがある。
// Person :
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
このstructに対して、structとして埋め込んだ PersonWithStruct
と interfaceとして埋め込んだ PersonWIthInterface
を用意してみる。以下のようなもの。
// PersonWithStruct :
type PersonWithStruct struct {
Person
Type string `json:"type"`
}
interfaceを埋め込んだものはこう。
// IPerson :
type IPerson interface{}
// PersonWithInterface :
type PersonWithInterface struct {
IPerson
Type string `json:"type"`
}
JSON化の結果
以下の様なコードを書いてJSON文字列に変換してみる。
func main() {
encoder := json.NewEncoder(os.Stdout)
encoder.SetIndent("", " ")
person := Person{Name: "foo", Age: 20}
{
wperson := PersonWithStruct{Type: "struct", Person: person}
if err := encoder.Encode(wperson); err != nil {
panic(err)
}
}
{
wperson := PersonWithInterface{Type: "interface", IPerson: person}
if err := encoder.Encode(wperson); err != nil {
panic(err)
}
}
}
結果は以下の様になる。
// structを埋め込んだもの(PresonWithStruct)
{
"name": "foo",
"age": 20,
"type": "struct"
}
// interfaceを埋め込んだもの(PeresonWithInterface)
{
"IPerson": {
"name": "foo",
"age": 20
},
"type": "interface"
}
structを埋め込んだ場合には出力結果がフラットになる一方で、interfaceを埋め込んだ場合はinterface名でラップされた形で出力される。
see also
goのissueを見るとこれは期待された結果らしい。