json.unmarshal 解析失败返回 error 而非 panic,需检查 err 并按场景处理;结构体字段须可导出且加 json tag 才能解析;null 值应使用指针类型;大 json 应优先用 json.decoder 流式解析。

json.Unmarshal 返回错误时,别直接 panic
Go 的 json.Unmarshal 在解析失败时返回 error,不是 panic。常见错误包括字段类型不匹配、JSON 格式非法、结构体字段不可导出等。直接忽略错误或用 panic(err) 会让服务在异常输入下崩溃,尤其在 HTTP API 中极危险。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
PHP5学习对象教程由美国人古曼兹、贝肯、瑞桑斯编著,简张桂翻译,电子工业出版社于2007年12月1日出版的关于PHP5应用程序的技术类图书。该书全面介绍了PHP 5中的新功能、编程方法及设计模式,还分析阐述了PHP 5中新的数据库连接处理、错误处理和XML处理等机制,帮助读者系统了解、熟练掌握和高效应用PHP。
- 始终检查
err != nil,并根据场景区分处理:对客户端返回 400 Bad Request,对内部日志记录原始 JSON 片段(注意脱敏) - 避免用空结构体接收任意 JSON:
var v interface{}+json.Unmarshal成功但后续类型断言失败,错误被延迟到运行时 - 若需宽松解析(如忽略未知字段),启用
DisallowUnknownFields()前先确认是否真需要——它会让含额外字段的合法请求失败
结构体字段没加 json tag 导致静默丢失数据
Go 结构体字段默认不会被 json.Unmarshal 解析,除非满足两个条件:字段名首字母大写(可导出),且有对应 json tag 或遵循默认命名规则(如字段 UserName 匹配 JSON 键 "user_name" 或 "userName")。没加 tag 又命名不匹配,字段就保持零值,无报错、无提示。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 所有参与 JSON 解析的结构体字段,显式加上
jsontag,例如:UserID int `json:"user_id"` - 使用
omitempty要谨慎:如果字段为零值(如0、""、nil),该字段在序列化时会被跳过;但反向解析时不影响,只是容易误以为“字段没传” - 嵌套结构体字段也需 tag,比如
Address AddressInfo `json:"address"`,否则整个Address字段为零值
处理 null 值:用指针或 sql.NullXXX 类型
JSON 中的 null 无法直接解到 Go 的非指针基础类型(如 int、string、bool),json.Unmarshal 会返回 json: cannot unmarshal null into Go value of type xxx 错误。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 对可能为
null的字段,用指针类型:*string、*int64,解完后判空:if req.Name != nil { use(*req.Name) } - 若需区分“未提供”和“明确设为 null”,可用自定义类型或三方库(如
guregu/null),但多数 API 场景指针已够用 - 注意指针解码后仍可能为
nil,不要直接 dereference,否则 panic
流式解析大 JSON 时,json.Decoder 比 Unmarshal 更稳
用 json.Unmarshal([]byte) 解析大 JSON(如 >1MB)会一次性加载全部内容到内存,易触发 OOM;且错误定位困难——只告诉你“解析失败”,不说明第几行哪一列。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 对 HTTP 请求体、文件等流式输入,优先用
json.NewDecoder(r).Decode(&v),它边读边解析,内存占用低 -
Decoder支持设置DisallowedUnknownFields()和自定义Number类型(避免 float64 精度丢失整数 ID) - 错误位置可通过包装
io.Reader实现行号追踪,例如用bufio.Scanner配合bytes.NewReader做调试,但生产环境通常只需记录原始 payload hash + 错误信息









