gcfg读不到[section]下值的主因是节名严格匹配大小写与空格、不自动trim、不支持点号等特殊字符,且BOM/CRLF处理缺失;必须用cfg.GetSections()确认真实节名,并手动清除BOM、替换换行符。

gcfg 不是推荐方案,它已多年未维护,不支持嵌套节、类型安全弱、错误提示模糊,线上项目请直接换用 gopkg.in/ini.v1。
为什么 gcfg 会读不到 [section] 下的值
gcfg 把无节名的键(如 username=root)归入 DEFAULT_SECTION,但对带方括号的节(如 [mysql])要求严格匹配大小写和空格——[mysql] 和 [MYSQL] 被视为不同节,且不自动 trim 节名前后空格。
常见表现:调用 cfg.GetValue("mysql", "host") 返回空字符串或 error,实际是因为节名被解析为 "mysql "(含尾部空格)。
- 必须用
go get gopkg.in/gcfg.v1,github.com/go-gcfg/gcfg是镜像,v1 分支已冻结 - 节名不能含点号(
[db.mysql]直接报错),也不能含冒号或短横线 - 读取前建议先调用
cfg.GetSections()打印所有节名,确认真实名称
gcfg.GetValue 返回空字符串却不报错的真相
GetValue() 在节不存在、键不存在、值为空字符串这三种情况下都返回 "",且 error 为 nil。你无法区分“配置没写”和“明确配了空值”。
- 务必搭配
cfg.HasSection(section)和cfg.HasKey(section, key)双重检查 - 不要依赖
if value == ""做逻辑分支,应先确认键存在:if cfg.HasKey("server", "port") { ... } - 数字/布尔字段必须手动
strconv.Atoi或strconv.ParseBool,gcfg 不提供MustInt()类型方法
gcfg 无法处理 UTF-8 BOM 和 Windows 换行符
若 ini 文件由 Windows 记事本或 VS Code 默认保存,很可能带 BOM(\xef\xbb\xbf)或 CRLF(\r\n),gcfg 会把 BOM 当作节名开头字符,导致 [mysql] 实际被识别为 "\xef\xbb\xbf[mysql]",后续所有读取失败。
立即学习“go语言免费学习笔记(深入)”;
- 加载前必须先读文件内容,用
bytes.TrimPrefix(data, []byte("\xef\xbb\xbf"))清除 BOM - 换行符统一用
strings.ReplaceAll(string(data), "\r\n", "\n")处理,再传给gcfg.ReadString() - 别用
gcfg.ReadFile()直接加载路径——它不做任何编码预处理
真正麻烦的不是语法解析,而是 gcfg 对错误容忍度太低、反馈太隐晦。一个空格、一个 BOM、一个大小写不一致,都会让你花半小时翻源码。生产环境请改用 gopkg.in/ini.v1,它默认忽略 BOM、节名自动 trim、错误信息带具体行号,且仍在活跃维护。


















