go json解析需首字母大写字段并配json标签,动态结构用json.rawmessage,时间用自定义类型或指针处理nil,大文件用json.newdecoder流式解析。

结构体字段必须首字母大写,否则解析为零值
Go 的 encoding/json 包只能访问导出字段(即首字母大写的字段),小写字段如 userName 或 createdAt 在 json.Unmarshal 时会被完全忽略,对应字段保持零值,且不报错——这是最隐蔽也最常踩的坑。
- 正确写法:
UserName string `json:"user_name"`(字段导出 + 标签映射) - 错误写法:
userName string `json:"user_name"`→ 解析后userName永远是空字符串 - 对接 snake_case API 时,别改 Go 命名习惯,统一用标签桥接:
DBHost string `json:"db_host"` - 想彻底排除某字段参与编解码?加
json:"-"标签,比注释掉更可靠
解析动态或不确定结构的 JSON,优先用 json.RawMessage 而非 map[string]interface{}
当 JSON 中某个字段类型不固定(比如 "data" 可能是对象、数组、字符串甚至 null),硬塞进 map[string]interface{} 会导致后续多层类型断言繁琐又易 panic;而 json.RawMessage 是 []byte 别名,只做字节暂存,不触发即时解析,更可控。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 推荐定义:
Data json.RawMessage `json:"data"` - 后续按需解析:
json.Unmarshal(user.Data, &targetStruct)或json.Unmarshal(user.Data, &targetMap) - 别直接对
map[string]interface{}做data["items"].([]interface{})断言——如果items是 null 或缺失,运行时直接 panic -
json.RawMessage赋值前需确保原始字节合法,否则Unmarshal时才暴露 JSON 语法错误
读文件、发 HTTP 请求时,别把 json.Unmarshal 当万能入口
json.Unmarshal 只接受 []byte,它不管数据从哪来。常见错误是:读文件用 ioutil.ReadFile(已弃用)、HTTP 响应体重复读、或手动转 string 再转回 []byte——全是多余拷贝和潜在 bug。
- 读小文件(≤100MB):用
os.ReadFile("config.json")直接得[]byte,然后传给json.Unmarshal(data, &v) - 处理大 JSON 流(如日志导入):用
json.NewDecoder(r.Body)或json.NewDecoder(file),边读边解,不占内存 - HTTP 响应中:先检查
resp.StatusCode == 200,再用json.NewDecoder(resp.Body).Decode(&v),避免中间 string 转换 - 务必 defer
resp.Body.Close(),否则连接泄漏
时间字段和 nil 值容易静默失败,必须显式约定格式或类型
time.Time 默认只认 RFC3339(如 "2026-04-01T05:09:00Z"),遇到 "2026-04-01" 或 "2026/04/01 05:09" 会静默设为零时间;数据库字段可能为 NULL,但普通结构体字段无法表达“不存在”,导致误判为默认零值。
- 时间字段建议封装新类型,实现
UnmarshalJSON支持多种格式,或统一用string接收再手动解析 - 可能为空的字段(如可空数据库列):用指针类型
*string、*int64或sql.NullString,而非原始类型 - 切片字段若 JSON 中为
null,[]string会变成nil,但len()仍安全;若需区分“空数组”和“null”,也得用*[]string
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










