
在 Go 中使用 json.Marshal 序列化包含嵌套结构体的类型时,若子结构体字段值为空(如空字符串),并非序列化逻辑出错,而是因未正确初始化嵌套结构体实例所致。
在 go 中使用 `json.marshal` 序列化包含嵌套结构体的类型时,若子结构体字段值为空(如空字符串),并非序列化逻辑出错,而是因未正确初始化嵌套结构体实例所致。
Go 的 json 包默认仅导出(首字母大写)且已赋值的字段。对于嵌套结构体(如 B.Bar 是类型 A),若未显式初始化其内部字段(例如 A{Zip: "35000"}),则 Zip 将保持零值(""),导致 JSON 输出中 "zip": ""。
以下是一个完整、可运行的示例,展示正确初始化方式:
package main
import (
"encoding/json"
"fmt"
)
type A struct {
Zip string `json:"zip"`
}
type B struct {
Foo string `bson:"foo"`
Bar A `json:"bar"`
}
func main() {
// ✅ 正确:显式构造嵌套结构体 A,并赋值
barValue := A{Zip: "35000"}
b := B{
Foo: "some-string-value",
Bar: barValue,
}
data, err := json.Marshal(b)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", data)
// 输出: {"foo":"some-string-value","bar":{"zip":"35000"}}
}⚠️ 常见错误排查点:
- 忘记为嵌套结构体字段赋值(如直接声明
Bar: A{}而未填充Zip); - 使用指针嵌套(如
Bar *A)但未分配内存(此时Bar为nil,JSON 中对应字段为null); - 字段名小写(如
zip string)导致无法导出——务必确保结构体字段首字母大写; - 错误地依赖零值初始化,误以为
json.Marshal会自动填充默认值(它不会)。
? 进阶建议:若需更灵活控制(如忽略空字段),可在标签中添加 ,omitempty:
type A struct {
Zip string `json:"zip,omitempty"`
}此时若 Zip == "",该字段将从 JSON 中完全省略。
总结:嵌套结构体的 JSON 序列化行为完全取决于其字段是否被正确初始化和导出。只要确保所有嵌套层级的导出字段均被显式赋值,json.Marshal 即可准确生成预期 JSON。


















