JSON データを Go 構造体にアンマーシャリングするのは簡単なタスクです。ただし、動的データ構造を含む JSON ドキュメントを扱う場合、フィールドのタイプが変化する可能性があり、プロセスがより複雑になる可能性があります。この記事では、一般的なプレースホルダー フィールドを導入せずに、この課題に対する解決策を検討します。
次の JSON 仕様を考慮してください。
{ "some_data": "foo", "dynamic_field": { "type": "A", "name": "Johnny" }, "other_data": "bar" }
{ "some_data": "foo", "dynamic_field": { "type": "B", "address": "Somewhere" }, "other_data": "bar" }
両方の JSON ドキュメントは次のとおりです。同じ Go 構造体にアンマーシャリングする:
type BigStruct struct { SomeData string `json:"some_data"` DynamicField Something `json:"dynamic_field"` OtherData string `json:"other_data"` }
重要な問題は、どのようにするかです。 Something タイプを作成し、アンマーシャリング ロジックを実装するには?
解決策には、Something タイプのインターフェイスの作成が含まれます:
type Something interface { GetType() string }
次に、Something インターフェイスを実装する特定の構造体の型を定義します。
type BaseDynamicType struct { Type string `json:"type"` } type DynamicTypeA struct { BaseDynamicType Name string `json:"name"` } type DynamicTypeB struct { BaseDynamicType Address string `json:"address"` }
DynamicType インターフェイス メソッドを使用すると、JSON データを適切な構造にアンマーシャリングできます。
func (d *DynamicType) UnmarshalJSON(data []byte) error { var typ struct { Type string `json:"type"` } if err := json.Unmarshal(data, &typ); err != nil { return err } switch typ.Type { case "A": d.Value = new(TypeA) case "B": d.Value = new(TypeB) } return json.Unmarshal(data, d.Value) }
このメソッドは、JSON データを検査し、必要に応じて TypeA または TypeB のインスタンスを作成します。
最後に、UnmarshalJSON メソッドをBigStruct 型:
func (b *BigStruct) UnmarshalJSON(data []byte) error { var tmp BigStruct // avoids infinite recursion return json.Unmarshal(data, &tmp) }
このメソッドは一時的な BigStruct 型を使用して再帰を回避し、JSON データの型フィールドに基づいて適切な DynamicType 型を使用して動的フィールドをアンマーシャリングできるようにします。
このソリューションは、追加の汎用コンポーネントを必要とせずに、動的 JSON データをアンマーシャリングするためのクリーンで効率的な方法を提供します。プレースホルダーフィールド。インターフェイスを採用し、カスタム UnmarshalJSON メソッドを実装することにより、Go 構造体は JSON 入力の動的データ構造に適応できます。
以上が汎用プレースホルダーフィールドを使用せずに Go で動的 JSON をアンマーシャリングする方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。