golangci-lint配置文件必须与go.mod同级且严格命名为.golangci.yml;多module项目需每个module单独配置,CI和IDE中均须显式指定--config=.golangci.yml才生效。

golangci-lint 配置文件必须放在 go.mod 同级目录
GoLand 本身不内置规则引擎,它依赖 golangci-lint 执行检查;而 golangci-lint 默认不读配置文件,除非你显式传参。常见错误是把 .golangci.yml 放在 src/ 下、或命名为 .golangci.yaml、或放在子 module 目录里——这些都会导致规则完全不生效。
正确做法只有一条:.golangci.yml 必须和 go.mod 在同一目录,且文件名严格为 .golangci.yml(不是 .yaml,也不是 golangci.yml)。
- 多 module 项目(如 monorepo)中,每个 module 都要单独放一份
.golangci.yml,父目录的配置不会继承 - CI 中尤其容易因工作目录错位(比如
cd ./service-a && golangci-lint run)导致漏读配置,建议统一用golangci-lint run --config=$(pwd)/.golangci.yml - 验证是否生效:在含未使用变量的文件里执行
golangci-lint run --config=.golangci.yml ./file.go,有报错才算通
启用 staticcheck 和 unused 是强制规范落地的关键
默认开启的 govet 和 errcheck 只能捕获基础问题,真正能约束“项目特定规范”的是 staticcheck 和 unused:
-
staticcheck能报SA1019(调用已弃用函数)、SA4006(无限 for 循环)、SA9003(布尔表达式恒真),这些是代码逻辑层面的硬性红线 -
unused会揪出未导出函数、无用 import、定义后从未读取的局部变量——直接清理技术债务,避免“写完就扔”的烂代码惯性 -
revive替代已归档的golint,支持自定义规则,比如禁止_ = foo()忽略 error,这是团队规范最常定制的点
别碰 dupl(重复代码)和 lll(行长限制)——前者阈值难调,易把合理复用判成重复;后者纯属风格偏好,不该卡 CI。
GoLand 2026.1.1 是 2026.1 发布后的首个维护修正版本,适合已经开始体验 2026.1 新功能并希望同步补丁的开发者。它更适合用于入门项目、现有项目迁移测试和 IDE 行为验证。
IDE 插件不亮红灯?先确认三处路径链
VS Code 或 GoLand 装了插件却没实时提示,大概率是路径断了:
- 插件设置里必须勾选「Use config file」,且路径填的是
.golangci.yml(不是相对路径、不是空值、不是./.golangci.yml) - IDE 启动时工作目录必须是含
go.mod的目录,否则它找不到配置文件或解析错 module path - 插件调用的
golangci-lint二进制版本要 ≥v1.52.0;旧版对revive规则支持不全,部分告警压根不触发
快速验证:在 IDE 内打开一个含未使用变量的 .go 文件,终端手动执行 golangci-lint run --config=.golangci.yml --no-config ./path/to/file.go,如果终端能报错但 IDE 不标红,就是插件路径或缓存问题。
格式化与检查要分离,别让 gofmt 干 linter 的活
gofmt 是格式工具,不是检查工具。它不报错、不警告、不支持配置——它的作用只是把缩进、括号、空格变成 Go 官方推荐样式。想靠它 enforce “项目特定规范”(比如禁止某 API、要求 error 必须处理)根本不可能。
- 格式化交给
gofmt或更常用的goimports(自动管理 import) - 规范检查必须由
golangci-lint承担,且必须配好.golangci.yml - GoLand 设置里「Go Linter」路径要指向你本地安装的
golangci-lint,不是gofmt,否则插件调用的是个哑巴命令
最常被忽略的细节:golangci-lint 启动时不读任何配置文件,除非显式传参;而 IDE 插件是否传参、传对参数,完全取决于你填的路径和勾选状态——这里一错,整个检查链就断了。

















