基於型別鍵解組動態JSON,不引入通用欄位
許多結構化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中struct:
type BigStruct struct { SomeData string `json:"some_data"` DynamicField Something `json:"dynamic_field"` OtherData string `json:"other_data"` }
挑戰在於定義「Something」類型,該類型可以根據「dynamic_field」物件中的「type」鍵容納動態資料。
避免需要對於明確的「通用」欄位(例如,值、資料),我們可以利用類型嵌入和
type BigStruct struct { SomeData string `json:"some_data"` DynamicField DynamicType `json:"dynamic_field"` OtherData string `json:"other_data"` } type DynamicType struct { Value interface{} }
在「DynamicType」中,「Value」欄位可以根據JSON 中的“type”鍵保存任何類型的資料。為了促進正確的解組,我們在「DynamicType」上實作UnmarshalJSON 方法:
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) }
我們為不同類型的資料定義特定類型:
type TypeA struct { Name string `json:"name"` } type TypeB struct { Address string `json:"address"` }
透過這種方法,我們可以解組JSON 文檔,無需額外的通用字段,使我們能夠維護乾淨且可擴展的資料結構。
以上是如何在沒有泛型欄位的情況下基於類型鍵在 Go 中解組動態 JSON?的詳細內容。更多資訊請關注PHP中文網其他相關文章!