应直接用json.unmarshal解析到结构体,避免先转map[string]interface{};嵌套结构用导体嵌套,字段须首字母大写并显式加json:"key"标签,null或缺失字段用指针类型,动态key用map[string]t。

直接用 json.Unmarshal 解析到结构体,别先转 map[string]interface{}——这是最稳、最可维护、IDE 能补全、编译期能报错的做法。嵌套再深也不怕,结构体一层套一层就行。
结构体字段必须首字母大写 + 显式加 json:"key" 标签
小写字母开头的字段(如 host string)会被 json 包完全忽略,解出来永远是零值;不加 json 标签时,Go 会尝试把 Host 自动映射成 "host",但一旦 JSON 里是 "db_host" 或 "DB-Host" 就失效。
- 所有要解析的字段必须首字母大写(即导出)
- 每个字段都建议显式写
json:"xxx",尤其当 JSON key 含下划线、中划线或大小写混杂时 - 嵌套结构体也一样:外层字段名大写,内层结构体本身也要大写首字母,且字段同样需导出+标签
嵌套对象为 null 或可能缺失时,用指针类型(如 *DBConfig)
常见错误:json: cannot unmarshal null into Go struct field Config.DB of type main.DBConfig——这是因为 JSON 里 "db": null,但结构体字段是值类型 DBConfig,无法接收 null。
- 把字段声明为
DB *DBConfig,null会自动转成nil,不会 panic - 后续使用前加
if c.DB != nil判断,语义清晰 - 避免用
sql.NullString等类型去套整个结构体,那是给单字段设计的
动态 key 名(比如环境名、ID 字符串作 key)必须用 map[string]T
例如 JSON 是 {"prod": {"host": "p.example.com"}, "dev": {"host": "d.example.com"}},没法硬编码字段名,这时结构体就该让位。
- 定义
type EnvConfig struct { Host string `json:"host"` },再声明Envs map[string]EnvConfig - 别写
map[string]map[string]interface{}——下一层取值又要断言,又易 panic - 如果需要区分“key 存在但值为 null”和“key 不存在”,用
map[string]*EnvConfig
读文件后必须检查 os.Open 和 json.Unmarshal 的错误
配置文件路径错、权限不足、JSON 格式非法,都会导致解析失败,但不检查错误就继续用,后面全是空值或 panic。
-
f, err := os.Open("config.json")→ 必须if err != nil处理 -
err := json.Unmarshal(data, &cfg)→ 必须检查err,不能只靠cfg是否为空判断 - 对大配置文件,优先用
json.NewDecoder(f).Decode(&cfg),边读边解,防 OOM
最容易被忽略的是:嵌套太深时,人容易把某一层结构体字段写成小写,或者漏掉某层的 json 标签——结果运行时不报错,但对应字段永远是零值,调试半天才发现是结构体没导出。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











