ホームページ >バックエンド開発 >Golang >カスタム MarshalJSON() メソッドを使用して構造体を埋め込むときに MarshalJSON() を正しく行う方法

カスタム MarshalJSON() メソッドを使用して構造体を埋め込むときに MarshalJSON() を正しく行う方法

Susan Sarandon
Susan Sarandonオリジナル
2024-12-16 07:22:10383ブラウズ

How to Correctly MarshalJSON() When Embedding Structs with Custom MarshalJSON() Methods?

カスタム MarshalJSON() メソッドを使用して構造体を埋め込む慣用的な方法

カスタム MarshalJSON() を使用して構造体を埋め込む

場合カスタム MarshalJSON() を使用した構造体の埋め込みメソッドを使用すると、外部構造体のフィールドがプロモートされた型にプロモートされ、埋め込まれた構造体の MarshalJSON() メソッドがオーバーライドされます。これにより、外部構造体をマーシャリングするときに予期しない結果が生じる可能性があります。

問題:

次の構造体を考慮してください:

type Person struct {
    Name string `json:"name"`
}

func (p *Person) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(p.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"}

Employee インスタンスに設定されているにもかかわらず、jobRole フィールドがありません。

解決策:

オプション1: 埋め込み型で MarshalJSON() を使用しない

  • Person 構造体から MarshalJSON() メソッドを削除します。
  • 代わりに、別の型 (例: Name) を作成します。 MarshalJSON() を実装します。
  • 使用する Person 構造体を更新します新しいタイプ (例: Person{Name: Name{"Bob"}})。
  • 従業員の構造体は、Name タイプからカスタム JSON エンコーディングを継承します。

オプション 2: MarshalJSON() をアウターに実装するタイプ

  • 従業員構造体に MarshalJSON() メソッドを実装します。
  • 埋め込まれた Person インスタンスの MarshalJSON() メソッドを呼び出して、その JSON 表現を取得します。
  • 人物の JSON を中間表現に非整形化します (例: map[string]interface{}).
  • 外部構造体のフィールドを中間表現に追加し、それを JSON にマーシャリングします。

注: 両方のオプションには、一部の手動処理が必要となり、最終的な JSON 出力のフィールドの順序に影響を与える可能性があります。

以上がカスタム MarshalJSON() メソッドを使用して構造体を埋め込むときに MarshalJSON() を正しく行う方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。