Golang如何实现可变字段的struct 减少JSON解析重复结构体定义
解决方案
有两种常用实现方案,可以完全避免重复定义meta字段,适配不同的Go版本使用场景:
方案1:使用泛型(推荐,Go 1.18及以上版本适用)
将外层通用结构体定义为泛型结构,把动态的data类型作为泛型参数传入,既保留类型安全特性,又实现了meta字段的复用。
// 公共meta结构体,只需要定义一次 type Meta struct { A string `json:"A"` B float64 `json:"B"` // 注意和实际JSON中B字段的类型匹配,避免解析报错 } // 通用外层JSON结构体,T为data字段的泛型参数 type CommonJSON[T any] struct { MetaData Meta `json:"meta"` Contents T `json:"data"` } // 不同业务场景仅需要定义各自的data结构即可 type Data1 struct { C string `json:"C"` } type Data2 struct { F string `json:"F"` }
使用时直接指定对应data的泛型参数即可:
// 解析data为Data1类型的JSON var json1 CommonJSON[Data1] err := json.Unmarshal([]byte(`{"meta":{"A":"AA", "B":123}, "data":{"C":"CC"}}`), &json1) // 解析data为Data2类型的JSON var json2 CommonJSON[Data2] err := json.Unmarshal([]byte(`{"meta":{"A":"DD", "B":456}, "data":{"F":"FF"}}`), &json2)
方案2:使用json.RawMessage延迟解析(兼容Go 1.18以下版本)
如果项目使用的Go版本不支持泛型,可以先将data字段保存为原始JSON字节,解析完公共meta字段后,再根据业务场景单独解析data内容:
type Meta struct { A string `json:"A"` B float64 `json:"B"` } type CommonJSON struct { MetaData Meta `json:"meta"` Contents json.RawMessage `json:"data"` // 先保存原始JSON字节不解析 }
使用时分两步解析:
// 第一步解析公共meta和原始data内容 var common CommonJSON err := json.Unmarshal([]byte(`{"meta":{"A":"AA", "B":123}, "data":{"C":"CC"}}`), &common) // 第二步根据当前业务场景解析对应类型的data var data1 Data1 err := json.Unmarshal(common.Contents, &data1)
内容的提问来源于stack exchange,提问作者mateoricfarm
相关产品推荐
相关产品推荐

