
本文讲解如何在 go 中灵活处理 json 反序列化后的结构改造,包括动态增删字段、嵌套结构重组及生成符合数据库要求的定制化 json 输出。
本文讲解如何在 go 中灵活处理 json 反序列化后的结构改造,包括动态增删字段、嵌套结构重组及生成符合数据库要求的定制化 json 输出。
在实际开发中,常需将原始 JSON 数据反序列化为中间结构后,再转换为另一种格式(如适配数据库 Schema 或第三方 API)。Go 的 encoding/json 包虽默认支持结构体映射,但不直接支持运行时动态字段裁剪或嵌套重组。此时需结合结构体解构 + 手动构造目标结构(或使用 map[string]interface{})来实现精准控制。
以需求为例:原始 JSON 含 companies 数组和 eventCCID 字段,但最终需输出仅含 companyID、预置空 entitlements 对象及固定 effective_date 的扁平化数组——即从 InterestedParties 转换为 []CompanyOutput。
✅ 推荐方案:定义目标输出结构体(类型安全、可维护性强)
type CompanyOutput struct {
CompanyID string `json:"companyID"`
Entitlements Entitlement `json:"entitlements"`
EffectiveDate string `json:"effective_date"`
}
type Entitlement struct {
Long string `json:"long"`
Voteable string `json:"voteable"`
Tabulation string `json:"tabulation"`
Confirm string `json:"confirm"`
}
// 转换逻辑
func transformToCompanyOutputs(ip InterestedParties) []CompanyOutput {
output := make([]CompanyOutput, 0, len(ip.Companies))
for _, c := range ip.Companies {
output = append(output, CompanyOutput{
CompanyID: c.CompanyID,
Entitlements: Entitlement{
Long: "",
Voteable: "",
Tabulation: "",
Confirm: "",
},
EffectiveDate: "2017-01-01",
})
}
return output
}
调用示例:
intPartiesJSON := `{"companies": [{"companyID":"COMP0001","companyType":"1","webAPI":"http://google.com"}, {"companyID":"COMP0002","companyType":"1","webAPI":"http://google.com"}],"eventCCID":"laksjlijivelnsvnklsnvlsv"}`
var intParties InterestedParties
json.Unmarshal([]byte(intPartiesJSON), &intParties)
result := transformToCompanyOutputs(intParties)
b, _ := json.Marshal(result)
fmt.Println(string(b))
// 输出:[{"companyID":"COMP0001","entitlements":{"long":"","voteable":"","tabulation":"","confirm":""},"effective_date":"2017-01-01"},{"companyID":"COMP0002","entitlements":{"long":"","voteable":"","tabulation":"","confirm":""},"effective_date":"2017-01-01"}]
⚠️ 注意事项
-
避免裸用
map[string]interface{}:虽然答案中给出map[string]interface{}示例能快速达成目的,但缺乏编译期校验、易出错且难以复用。仅建议用于原型验证或极简一次性转换。 -
字段零值处理:
Entitlement{}默认初始化所有字段为空字符串,符合 JSON 序列化预期;若需null,应改用指针类型(如*string)并显式设为nil。 -
性能考量:对大数据量场景,可复用
bytes.Buffer或预分配切片容量(如示例中make(..., 0, len(ip.Companies)))减少内存分配。 -
扩展性设计:若
effective_date需动态传入,可将transformToCompanyOutputs改为接收参数effectiveDate string;若Entitlement字段需按规则填充,可封装为独立函数。
通过结构体驱动的显式转换,代码更清晰、可测试、易协作,是 Go 工程中处理 JSON 格式转换的推荐实践。











