基于类型键解组动态 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中文网其他相关文章!