基於型別鍵解組動態JSON
當JSON 結構包含動態欄位時,將複雜的JSON 資料解組到Go 結構中可能具有挑戰性不同類型的。本文討論了一個特定場景,其中 JSON 欄位主要包含簡單值,但有時具有特定類型鍵的動態欄位決定欄位值的類型。
目標是建立一個具有相同結構的 Go 結構體結構作為提供的 JSON,其中動態欄位表示為介面類型,允許根據其類型進行靈活處理。
一個可能的解決方案利用以下自訂類型:
type BigStruct struct { SomeData string `json:"some_data"` DynamicField Something `json:"dynamic_field"` OtherData string `json:"other_data"` } type Something interface { GetType() string }
然後,為每個動態欄位類型建立單獨的結構:
type BaseDynamicType struct { Type string `json:"type"` } type DynamicTypeA struct { BaseDynamicType Name string `json:"name"` } type DynamicTypeB struct { BaseDynamicType Address string `json:"address"` } func (d *BaseDynamicType) GetType() string { return d.Type }
要將JSON 解組到此結構中,BigStruct 可以實作自訂UnmarshalJSON 方法:
func (b *BigStruct) UnmarshalJSON(data []byte) error { var tmp struct { SomeData string `json:"some_data"` DynamicField json.RawMessage `json:"dynamic_field"` OtherData string `json:"other_data"` } if err := json.Unmarshal(data, &tmp); err != nil { return err } b.Unmarshal(tmp.DynamicField) return nil }
可以從UnmarshalJSON 中呼叫Unmarshal 方法來解析動態field:
func (b *BigStruct) Unmarshal(data json.RawMessage) error { switch UnmarshalledType(data) { case "A": var a DynamicTypeA if err := json.Unmarshal(data, &a); err != nil { return err } b.DynamicField = &a case "B": var b DynamicTypeB if err := json.Unmarshal(data, &b); err != nil { return err } b.DynamicField = &b } return nil } func UnmarshalledType(b json.RawMessage) string { var typ struct { Type string `json:"type"` } if err := json.Unmarshal(b, &typ); err != nil { log.Fatalf("Error extracting type from RawMessage: %v", err) } return typ.Type }
透過這種方法,您可以將動態JSON 欄位解組到Go 結構中,而無需引入額外的佔位符字段。
以上是如何根據類型鍵解組 Go 中的動態 JSON 欄位?的詳細內容。更多資訊請關注PHP中文網其他相關文章!