gopkg.in/ini.v1 默认区分 section 大小写,需显式启用 Insensitive:true;JSON 解析要求字段导出且正确声明 json tag;INI 与 JSON 混用时环境变量覆盖需手动实现,错误提示粒度差异大,易静默失败。
gopkg.in/ini.v1 读取 INI 文件时,section 名区分大小写INI 文件默认按 section 名做键匹配,而 gopkg.in/ini.v1 的 GetSection() 和 Sections() 默认区分大小写。若配置中写的是 [Database],但代码里调用 cfg.GetSection("database"),会返回 nil,不报错也不提示。
cfg.SectionStrings() 查看所有实际 section 名,确认大小写ini.LoadOptions{Insensitive: true} 启用不区分大小写的查找[db_config] vs [DBConfig]),统一团队命名约定cfg, err := ini.LoadSources(ini.LoadOptions{Insensitive: true}, "config.ini")
if err != nil {
log.F
atal(err)
}
dbSec := cfg.Section("database") // 现在能匹配 [Database] 或 [DATABASE]
json tagGo 的 encoding/json 只能序列化/反序列化导出字段(首字母大写),且若字段名与 JSON key 不一致,必须用 json: tag 显式声明。漏掉 tag 或写错 key 名会导致字段始终为零值,无错误提示。
port int)永远读不到值json:"port" 和 json:"port,string" 行为不同:后者会把字符串格式的数字(如 "8080")自动转为 intjson:",omitempty" 可跳过零值字段,但注意布尔类型 false、整型 0 也会被忽略type Config struct {
DBHost string `json:"db_host"`
DBPort int `json:"db_port,string"`
Debug bool `json:"debug,omitempty"`
}
var cfg Config
if err := json.Unmarshal(data, &cfg); err != nil {
log.Fatal(err)
}
INI 和 JSON 库本身都不支持像 viper 那样自动按优先级合并多源配置。若你同时加载 config.ini 和 config.json,再想用 os.Getenv("DB_PORT") 覆盖其中某项,必须自己写逻辑——库不会帮你做 fallback。
os.Getenv()
strconv.Atoi(os.Getenv("X")) 并判断 error,别直接强制转换ini 和 json 的错误信息粒度差异很大encoding/json 在解析失败时通常只报“invalid character … at offset N”,不指明是哪个字段;而 gopkg.in/ini.v1 报错更具体,例如 “line 12: unknown field 'log_level' in section 'server'”。这意味着 JSON 配置出错更难定位。
\r\n)可能导致解析器误判行号,用 unix2dos 或编辑器转 LFdefer 中关闭文件句柄,并检查 os.Open 是否出错——这是最常被忽略的第一道关卡