go 的 encoding/json 默认不支持私有字段解析,结构体字段必须首字母大写且带 json 标签才能正确反序列化;需检查 error、注意类型严格匹配、合理使用 omitempty/- 标签、动态字段用 map[string]interface{} 或 json.rawmessage,并警惕时间与大整数精度问题。

Go 的 encoding/json 默认不支持私有字段解析,结构体字段必须首字母大写且带 json 标签才能正确反序列化。
结构体字段必须导出(首字母大写)才能被 json.Unmarshal 读取
Go 的反射机制无法访问未导出(小写开头)字段,即使加了 json 标签也无效。常见错误是定义了类似 type User struct { name string `json:"name"` },结果解析后 name 始终为空。
- 必须写成
type User struct { Name string `json:"name"` } - 如果字段名与 JSON key 不一致,靠
json标签映射,如ID int `json:"user_id"` - 想忽略某个字段,用
-标签:TempData string `json:"-"` - 想允许空值或缺失时设为零值(而非报错),可用
omitempty:Age int `json:"age,omitempty"`
json.Unmarshal 遇到类型不匹配会静默失败或 panic,需检查返回 error
比如把 JSON 字符串 {"count": "123"} 解析进 Count int 字段,json.Unmarshal 会返回 json: cannot unmarshal string into Go struct field ... of type int 错误 —— 但很多人只看结构体值、忽略 error 判断,导致逻辑跑飞。
- 务必检查
err != nil,尤其在处理外部输入(API 响应、配置文件)时 - 数字类型严格区分:JSON
123可转int,但"123"不行;浮点数同理 - 布尔值只认
true/false,"true"字符串会报错 - 嵌套对象或数组类型不一致(如期望
[]string却收到null)也会触发 error
处理未知或动态 JSON 字段:用 map[string]interface{} 或 json.RawMessage
当 JSON 结构不确定(如第三方 API 返回字段可能增减)、或某字段需要延迟解析(如根据 type 字段决定后续结构),硬写结构体会很脆弱。
立即学习“go语言免费学习笔记(深入)”;
-
map[string]interface{}适合快速探查,但类型断言繁琐:v, ok := data["items"].([]interface{}) -
json.RawMessage更高效:它把一段 JSON 字节流暂存为未解析的[]byte,等真正需要时再调用json.Unmarshal,避免重复解析和中间类型转换开销 - 示例:
type Event struct { Type string `json:"type"` Data json.RawMessage `json:"data"` },之后按Type分支解出具体结构
最容易被忽略的是时间字段和数字精度问题:JSON 没有原生日期类型,通常传字符串(需手动用 time.UnmarshalText);而 float64 解析大整数(如 17 位以上 ID)会丢失精度 —— 这时候得用 json.Number 或字符串接收后再转。










