结构体字段未赋值主因是字段未导出、未传指针或json标签错误;须首字母大写导出字段、传地址符&变量、正确使用双引号标签如json:"id",并用RawMessage处理动态字段。

结构体字段没被赋值?八成是字段没导出、没传指针,或者标签写错了。
结构体字段必须首字母大写才能被反序列化
小写字母开头的字段(如 name string)在 json.Unmarshal 时会被完全忽略,不报错、不警告,字段保持零值。这是最隐蔽也最常踩的坑。
- 把
name改成Name,确保字段可导出 -
json标签里的键名可以小写,不影响映射:`json:"user_name"` - 如果结构体来自第三方包且无法改字段名,只能绕过结构体,先用
map[string]interface{}接收再手动赋值
json.Unmarshal 必须传指针,否则字段不会更新
传值调用(json.Unmarshal(data, p))编译能过,但解析成功后 p 仍是空结构体——因为 Unmarshal 写的是副本,不是原变量。
- 正确写法:
err := json.Unmarshal(data, &p) - 对切片也一样:
var users []User; json.Unmarshal(data, &users) - 用
new(T)或&T{}初始化后传指针,别传零值变量本身
json 标签写错会导致字段映射失败
标签格式错误(比如漏双引号、冒号写成等号、拼写错误)会让 Unmarshal 找不到对应字段,静默跳过。
在 Go 中使用 google/wire 实现编译时依赖注入——wire.NewSet、wire.Build、wire.Bind(接口→实现)、wire.Struct、wire.Value、wire.Interface
立即学习“go语言免费学习笔记(深入)”;
- 正确格式:
`json:"id"`或`json:"user_id,omitempty"`,双引号不能少 -
json:"host"和json:host(无引号)效果完全不同,后者会被忽略 -
omitempty只影响序列化,不影响反序列化;但它可能掩盖“字段确实为 0”还是“压根没传”的业务逻辑差异
嵌套结构或类型不确定时别硬塞进固定结构体
当 JSON 的某个字段可能是对象、数组或 null,直接定义成 type Address struct{...} 并嵌入,容易 panic 或字段为空。
- 先用
Data json.RawMessage `json:"data"`拿原始字节,避免提前解析失败 - 后续根据
len(Data) > 0和首字符({/[/n)判断类型,再分发解析 -
map[string]interface{}灵活但类型不安全,深层嵌套时result["data"].(map[string]interface{})["items"].([]interface{})容易 panic,建议仅用于顶层路由分发或调试
真正难的不是写对语法,而是确认字段“真的进来了”——反序列化后立刻检查关键字段是否仍为零值,比读文档更可靠;打印 len(data) 和 string(data) 前几字符,比猜结构更直接。

















