必须用golangci-lint而非单独工具:golint已归档禁用;govet默认漏检unmarshal等高危项;staticcheck单独运行易因路径或模块模式报错;而golangci-lint并行调度多linter,统一配置、超时与输出,ci中一条命令即覆盖全维度检查。

别装 golint,也别手动跑 go vet 或 staticcheck 单独命令——直接装 golangci-lint 并配好 .golangci.yml,这是当前 Go 项目唯一靠谱的静态检查起点。
为什么必须用 golangci-lint 而不是单独工具
官方早在 2021 年就归档了 golint,它规则主观、不维护、噪音大;go vet 默认只开几个子检查(比如 printf),漏掉 unmarshal、shadow 这类高危项;staticcheck 单独运行容易报 no Go files in directory——八成是你没在 go.mod 根目录,或 GO111MODULE=off。
而 golangci-lint 是聚合入口:它并行调度 govet、staticcheck、errcheck 等底层 linter,统一处理配置、路径排除、超时和输出格式。CI 里一条 golangci-lint run --timeout=3m 就覆盖语义、风格、错误处理三层检查。
- 不装
golint:它已禁用,任何残留配置(如.golangci.yml里还开着golint)都会导致误报或失败 - 不手动跑
go vet -unmarshal ./:golangci-lint内置调用,只需在配置里显式启用govet的子检查项 - 不单独升级
staticcheck:它的版本应由golangci-lint发布周期管理,混用易出兼容问题
golangci-lint 安装与基础配置
安装推荐用官方脚本(跨平台、版本可控):
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.54.2
验证:golangci-lint --version。接着在项目根目录生成默认配置:
golangci-lint config init
这会生成 .golangci.yml。关键修改点:
- 删掉
golint:在linters.enable列表里移除它,或加linters.disable: ["golint"] - 强制启用
govet全量检查:linters-settings.govet.checks: ["all"](Go 1.21+ 支持) - 必开
staticcheck和errcheck:它们分别抓死代码/类型断言错误、未处理 error - 跳过干扰路径:
run.skip-dirs: ["vendor", "third_party", "generated"]
govet 不报错?大概率是配置没生效
写了 json.Unmarshal(b, &v) 却没警告?说明 govet 的 unmarshal 子检查被关了。默认白名单只含 printf、shadow 等几个,不包括 atomic、bools、unmarshal。
实操确认步骤:
- 查
.golangci.yml里有没有linters-settings.govet段;没有就等于用默认白名单 - 加
checks: ["all"],或明确列出:checks: ["printf", "shadow", "unmarshal", "atomic", "bools"] - 确认
run.skip-dirs没把当前包路径正则匹配误伤(比如写成"pkg.*"却匹配到了pkg/api) - 本地改完逻辑后,可补一句
go vet -tags=dev ./快速过一遍,它比golangci-lint更轻量
VS Code 不显示 lint 提示?不是插件坏了,是走错了通道
VS Code 的 Go 插件(golang.go)默认用 gopls 提供实时 lint,而 gopls 完全不读 .golangci.yml。你改了配置,编辑器毫无反应,是因为根本没调用 golangci-lint。
要让编辑器实时显示 golangci-lint 结果,必须切到外部命令模式:
- 在 VS Code 设置中,设
"go.lintTool": "golangci-lint" - 确保
"go.useLanguageServer": false或至少关掉gopls的内置 lint("gopls": {"ui.diagnostic.staticcheck": false}) - 重启编辑器,错误会以波浪线形式出现在代码行下,悬停看详情
- 注意:保存自动修复(
--fix)仅对gofmt、goimports类支持,别指望它修staticcheck报的死代码
复杂点在于,govet 和 staticcheck 都依赖模块上下文和类型图谱,首次运行慢、对 replace 路径敏感、且无法跨 module 边界分析——这些不是配置能绕开的,得接受它本来就这样。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











