將 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"` }
The 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 的實例。
最後,在BigStruct 上實作UnmarshalJSON 方法type:
func (b *BigStruct) UnmarshalJSON(data []byte) error { var tmp BigStruct // avoids infinite recursion return json.Unmarshal(data, &tmp) }
此方法使用臨時來避免「資料中的類型欄位使用適當的DynamicType 類型對動態欄位進行解組。
該解決方案提供了一種乾淨有效的方法來解組動態 JSON 數據,而不需要額外的通用佔位符字段。透過使用介面並實作自訂 UnmarshalJSON 方法,Go 結構體可以適應 JSON 輸入中的動態資料結構。
以上是如何在沒有通用佔位符字段的情況下在 Go 中解組動態 JSON?的詳細內容。更多資訊請關注PHP中文網其他相關文章!