埋め込まれた構造体がカスタマイズされた MarshalJSON() メソッドを定義するときに問題が発生し、予期しない JSON シリアル化動作が発生します。含まれているものをマーシャリングしようとするときstruct.
次の構造体定義を考えてみましょう:
type Person struct { Name string `json:"name"` } type Employee struct { *Person JobRole string `json:"jobRole"` }
期待どおりに Employee 構造体をマーシャリングするのは簡単です:
p := Person{"Bob"} e := Employee{&p, "Sales"} output, _ := json.Marshal(e) fmt.Printf("%s\n", string(output))
出力:
{"name":"Bob","jobRole":"Sales"}
ただし、以下に示すように、埋め込み構造体にカスタム MarshalJSON() メソッドを定義すると、意図したシリアル化が中断されます。
func (p *Person) MarshalJSON() ([]byte, error) { return json.Marshal(struct{ Name string `json:"name"` }{ Name: strings.ToUpper(p.Name), }) }
現在、Employee をマーシャリングすると、name フィールドを含む出力が生成されます。大文字に変換されましたが、jobRole フィールドが欠落しています:
{"name":"BOB"}
必要なシリアル化動作を維持するには、埋め込み構造体 (Person) で MarshalJSON() メソッドを定義しないようにします。代わりに、カスタム マーシャリング ロジックをカプセル化する別の型を作成し、その型を埋め込みます。
type Name string func (n Name) MarshalJSON() ([]byte, error) { return json.Marshal(struct{ Name string `json:"name"` }{ Name: strings.ToUpper(string(n)), }) } type Person struct { Name Name `json:"name"` }
このアプローチでは、マーシャリングのカスタマイズが専用の型に分離され、他の場所に Person 構造体を埋め込む際の予期せぬ副作用が防止されます。
例: https://play.golang.org/p/u96T4C6PaY
以上がGo でカスタム `MarshalJSON()` を使用して構造体を慣用的に埋め込む方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。