
在 Go 中,当结构体字段包含另一个结构体时,若嵌套字段的值为空(如未初始化或零值),json.Marshal 会如实输出其零值(如空字符串),并非序列化失败——关键在于确保嵌套结构体实例已正确初始化并赋值。
在 go 中,当结构体字段包含另一个结构体时,若嵌套字段的值为空(如未初始化或零值),`json.marshal` 会如实输出其零值(如空字符串),并非序列化失败——关键在于确保嵌套结构体实例已正确初始化并赋值。
Go 的 json.Marshal 对嵌套结构体的序列化是完全支持且可靠的,但其行为严格遵循字段的实际值。以如下定义为例:
type A struct {
Zip string `json:"zip"`
}
type B struct {
Foo string `bson:"foo"`
Bar A `json:"bar"`
}问题中出现 {"foo": "some-string-value", "bar": {"zip": ""}} 的根本原因,并非标签错误或嵌套不被支持,而是 Bar 字段所对应的 A 实例未被显式赋值(即使用了零值 A{}),导致其 Zip 字段为默认空字符串 ""。
✅ 正确做法是:在构造 B 实例时,确保 Bar 字段被赋予一个已初始化的 A 值:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
func main() {
b := B{
Foo: "some-string-value",
Bar: A{Zip: "35000"}, // 显式初始化嵌套结构体
}
data, err := json.Marshal(b)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data))
// 输出: {"foo":"some-string-value","bar":{"zip":"35000"}}
}⚠️ 注意事项:
- 结构体字段必须是导出的(首字母大写) 才能被
json包访问;本例中A和B均满足,无需额外处理。 - JSON 标签(如
`json:"zip"`)仅控制键名与忽略逻辑,不影响值是否为空;空值源于 Go 层面的初始化状态,而非标签配置。 - 若需延迟初始化或可选嵌套结构,可将
Bar改为指针类型(*A),此时未赋值则为null,且能区分“未设置”与“显式为空”:type B struct { Foo string `bson:"foo"` Bar *A `json:"bar,omitempty"` // nil 时整个字段被忽略 }
总结:嵌套结构体 JSON 序列化失败的常见陷阱是忽略 Go 的零值语义。务必检查嵌套字段是否已被显式构造并赋值——这不是序列化限制,而是数据初始化责任。

















