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