Unmarshal Dynamic JSON Berdasarkan Kekunci Jenis
Menyahmarshal data JSON kompleks ke dalam struct Go boleh mencabar apabila struktur JSON mengandungi medan dinamik daripada pelbagai jenis. Artikel ini menangani senario tertentu di mana medan JSON kebanyakannya mengandungi nilai mudah, tetapi kadangkala medan dinamik dengan kunci jenis tertentu menentukan jenis nilai medan.
Matlamatnya adalah untuk mencipta struct Go dengan perkara yang sama struktur sebagai JSON yang disediakan, di mana medan dinamik diwakili sebagai jenis antara muka, membenarkan pengendalian yang fleksibel berdasarkan jenisnya.
Satu kemungkinan penyelesaian menggunakan jenis tersuai berikut:
type BigStruct struct { SomeData string `json:"some_data"` DynamicField Something `json:"dynamic_field"` OtherData string `json:"other_data"` } type Something interface { GetType() string }
Kemudian, cipta struct individu untuk setiap jenis medan dinamik:
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 }
Untuk menyahmarshal JSON ke dalam struct ini, BigStruct boleh melaksanakan tersuai Kaedah 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 }
Kaedah Unmarshal boleh dipanggil dari dalam UnmarshalJSON untuk menghuraikan medan dinamik:
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 }
Dengan pendekatan ini, anda boleh menyahmarshal medan JSON dinamik ke dalam struct Go tanpa memperkenalkan medan pemegang tempat tambahan.
Atas ialah kandungan terperinci Bagaimana untuk Menyahmarshal Medan JSON Dinamik dalam Go Berdasarkan Kunci Jenis?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!