LoginSignup
5
6

More than 5 years have passed since last update.

goでstructをJSONに変換した時の結果が、埋め込みのフィールドがinterfaceである場合とstructである場合で異なる

Last updated at Posted at 2017-02-01

はじめに

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を見るとこれは期待された結果らしい。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6