カスタム MarshalJSON() メソッドを使用して構造体を埋め込む慣用的な方法
以下の構造体を考慮すると、Employee 構造体を次のように簡単に JSON にマーシャリングできます。予想:
type Person struct { Name string `json:"name"` } type Employee struct { *Person JobRole string `json:"jobRole"` }
ただし、埋め込まれた構造体にカスタム MarshalJSON() メソッドがある場合、マーシャリング プロセスが中断されます:
func (p *Person) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Name string `json:"name"` }{ Name: strings.ToUpper(p.Name), }) }
これは、埋め込まれた Person 構造体が MarshalJSON() 関数を実装しており、この関数が Employee 構造体自体の MarshalJSON よりも優先されるためです。 () メソッド。
望ましい出力は、Employee フィールドを通常どおりエンコードすることです。パーソンの MarshalJSON() メソッドに準拠してフィールドをマーシャリングします。ただし、MarshalJSON() メソッドを Employee に追加するには、埋め込み型が MarshalJSON() も実装していることを理解しておく必要があり、これは脆弱である可能性があります。
この問題を解決するには、別のアプローチを使用できます。
人の名前を表す新しいタイプの名前を作成しますname:
type Name string
Name に MarshalJSON() を実装してエンコーディングをカスタマイズします:
func (n Name) MarshalJSON() ([]byte, error) { return json.Marshal(strings.ToUpper(string(n))) }
Name を使用するように Person 構造体を変更しますの代わりにstring:
type Person struct { Name Name `json:"name"` }
このアプローチにより、Employee 構造体に MarshalJSON() メソッドを必要とせずに、個人名のエンコーディングをカスタマイズできます。
あるいは、次の場合これをより一般的に実装したいので、外側の型に MarshalJSON を実装する必要があります。内部型のメソッドは外部型に昇格されるため、内部型の MarshalJSON メソッドを呼び出し、その出力を map[string]interface{} のような汎用構造にアンマーシャルし、独自のフィールドを追加できます。ただし、これには、最終出力フィールドの順序が変更されるという副作用が生じる可能性があります。
以上がGo で慣用的にカスタム `MarshalJSON()` メソッドを使用して構造体を埋め込む方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。