golangci-lint装完默认仅启用govet、errcheck等少数linter,staticcheck、unused等关键检查器需通过同级go.mod目录下的.golangci.yml显式启用;多module项目须每个module单独配置,ci和ide中均需显式指定--config=.golangci.yml才生效。

装完 golangci-lint 不等于代码就开始被检查了——它默认只开 govet 和 errcheck,staticcheck、unused 这些真正揪 bug 的检查器全关着,不配 .golangci.yml 就等于白装。
为什么 golangci-lint run 没报错却没效果
根本原因是配置文件没生效或压根不存在。它不会自动启用所有 linter,也不会继承父目录配置。
-
.golangci.yml必须和go.mod在同一级目录;写成.golangci.yaml或丢在src/里都无效 - 多 module 项目(比如 monorepo)中,每个 module 都得单独放一份配置,不能只在根目录放一个
- CI 中直接跑
golangci-lint run很容易漏读配置,务必显式加参数:golangci-lint run --config=.golangci.yml - VS Code 的 Go 插件也要手动勾选「使用配置」并填对路径,否则可能沿用旧缓存或默认规则
必须启用的 5 个核心 linter
不是“建议”,而是实际项目中误报低、问题暴露率高的最小有效组合:
-
govet:查类型不匹配、死循环、shadowing 等基础语义问题 -
errcheck:强制检查 error 是否被处理,避免静默失败 -
staticcheck:报SA1019(调用弃用 API)、SA4006(死循环)等真实风险 -
unused:发现未使用的变量、函数、import,清理技术债务 -
revive:替代已弃用的golint,支持自定义规则(如禁止_ = xxx忽略 error)
别碰 dupl(重复代码检测)和 lll(行长限制)——前者阈值难调、易误报,后者纯属风格偏好,不该卡 CI。
CI 里 golangci-lint 卡住或超时怎么办
常见于 GitHub Actions / GitLab CI,本质是资源没控住,不是工具本身慢。
- 加
--concurrency=2:CI 通常只有 2 vCPU,不设会争抢资源 - 加
--timeout=2m:防止单次分析无限 hang 住整条流水线 - 加
--fast:跳过goconst、gocyclo等耗时 linter,保留上面 5 个核心项即可 - 缓存
~/.cache/golangci-lint:否则每次重编译 linter,启动就慢半分钟
--fast 在 IDE 里也要开,否则编辑器会卡顿;但本地全量扫描仍建议定期去掉该 flag,跑一次深度检查。
如何跳过某行或整个文件的检查
不是为了绕过问题,而是应对生成代码、兼容性适配等真实例外场景。
- 跳过某一行:
//nolint:gosimple(仅禁用指定 linter),或//nolint(禁用所有) - 跳过整个文件:在文件顶部第一行加
//nolint,或在.golangci.yml的exclude-files列表中声明正则,比如"\.gen\.go$" - 跳过目录:在
.golangci.yml的run.skip-dirs下添加,如["generated", "migrations"]
最容易被忽略的是:skip-dirs 和 exclude-files 是字符串列表,不是 glob 模式,路径匹配基于文件系统路径,不是包路径。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











