ホームページ >バックエンド開発 >Golang >Go でカスタム `MarshalJSON()` を使用して構造体を慣用的に埋め込む方法は?

Go でカスタム `MarshalJSON()` を使用して構造体を慣用的に埋め込む方法は?

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-06 13:18:11279ブラウズ

How to Idiomatically Embed a Struct with a Custom `MarshalJSON()` in Go?

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

埋め込まれた構造体がカスタマイズされた MarshalJSON() メソッドを定義するときに問題が発生し、予期しない JSON シリアル化動作が発生します。含まれているものをマーシャリングしようとするときstruct.

Background

次の構造体定義を考えてみましょう:

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 サイトの他の関連記事を参照してください。

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