golangci-lint 默认仅启用少量 linter(如 govet、errcheck),未启用 unused、staticcheck 等关键检查,故无法发现未使用变量、nil 解引用等 bug;需通过 .golangci.yml 显式配置。

golangci-lint 为什么检查不出我刚写的 bug?
默认配置下,golangci-lint 只启用了一小部分 linter(比如 govet、errcheck),很多常见问题如未使用的变量、冗余 import、潜在的 nil 指针解引用,默认是不报的。
- 运行
golangci-lint run --help查看当前启用的 linter 列表,注意--enable-all并不推荐用于日常开发——它会开启大量实验性/高误报率检查 - 真正实用的做法是:在项目根目录加
.golangci.yml,显式启用几个关键 linter:unused(检测未使用标识符)、goconst(检测重复字面量)、gosimple(简化代码)、staticcheck(深度静态分析) - 注意
staticcheck和unused在 Go 1.21+ 中对泛型支持更稳,旧版本可能漏报或 panic
如何让 golangci-lint 只检查改动的文件?
直接 golangci-lint run 会扫整个 ./...,CI 或 PR 场景下太慢,也容易掩盖新引入的问题。
- Git 场景下用
git ls-files -m -o --exclude-standard | grep '\.go$' | xargs golangci-lint run,但注意空输入时 xargs 会失败,建议加-r参数 - 更可靠的是用
golangci-lint run --new-from-rev=HEAD~1,它基于 git diff 自动识别新增/修改的 .go 文件(要求工作区干净,且 HEAD~1 可达) - 如果用在 CI 中,别依赖
HEAD~1—— 合并 PR 时 base 分支可能已更新,应改用--new-from-rev=$BASE_SHA,由 CI 系统传入基线 commit
golangci-lint 报 SA1019: xxx is deprecated 但我不想改怎么办?
这是 staticcheck 发出的警告,说明你用了被标记为 Deprecated 的函数或方法。不是错误,但提示风险。
- 临时忽略:在调用行上方加
//nolint:staticcheck,仅对该行生效;若想忽略整个文件,在文件顶部加//nolint:staticcheck // reason - 全局禁用该检查:在
.golangci.yml中写disable: ["SA1019"],但不建议——它可能掩盖真实兼容性问题 - 真正要小心的是:Go 标准库里被标 deprecated 的 API(比如
http.CloseNotifier),很可能在下一个 minor 版本就彻底移除;第三方库则要看维护者是否真会删
CI 中 golangci-lint 失败但本地正常?
最常见原因是 Go 版本或 linter 版本不一致,其次是缓存和模块加载路径差异。
- CI 脚本里必须固定
golangci-lint版本,例如用curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.54.2,别用latest - 确保 CI 使用的 Go 版本与本地一致(
go version输出需完全匹配),尤其注意go1.21.0和go1.21.1对某些 linter 行为有细微差别 - CI 环境中
go mod download可能没执行完就跑 lint,导致type not found类错误,应在golangci-lint run前加go mod download
最常被跳过的其实是配置文件的继承逻辑:.golangci.yml 不会自动从父目录向上查找,每个子模块都得有自己的配置,或者统一放在 monorepo 根目录并用 run --config=.golangci.yml 显式指定路径。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











