unused检查器默认关闭,需在与go.mod同级的.golangci.yml中显式启用enable: [unused],多模块项目须各模块单独配置,CI和IDE需显式指定--config=.golangci.yml才生效。

unused 检查器默认是关着的
装完 golangci-lint 后直接跑 golangci-lint run,unused 不会生效——它不在默认启用列表里。你看到的 “未使用变量/函数/导入” 报错,大概率来自 govet 或旧版 deadcode(已弃用),不是真正的 unused。后者更准、覆盖更全,能识别测试文件里的 var tt testCase、废弃的 benchTest 函数等。
.golangci.yml 必须和 go.mod 同级且命名严格
配置 unused 只有一步:在项目根目录(即 go.mod 所在目录)创建 .golangci.yml,内容至少包含:
linters:
enable:
- unused
注意以下几点:
-
.golangci.yaml、.golangci.yml.bak、放在src/或子模块目录下,全部无效 - 多 module 项目(如 monorepo)中,每个 module 都得单独放一份
.golangci.yml,根目录的配置不会继承 - CI 中必须显式加
--config=.golangci.yml,否则可能读不到;VS Code 的 Go 插件也要手动勾选「使用配置」并填对路径
为什么启用了 unused 还不报 test 文件里的死代码?
unused 默认检查所有 .go 文件,包括 *_test.go,但有两个常见干扰项:
- 测试函数名以
Test、Benchmark、Example开头的,会被视为“已使用”,即使没被调用;但像func helper() {}或var tt testCase这类纯辅助声明,仍会被标记 - 如果测试文件里用了
_ = xxx忽略返回值,而该值所属类型没被其他地方引用,unused仍会报其类型定义未使用——这不是 bug,是它在清理技术债务 - 确认没在配置里写
skip-dirs: test或exclude-rules误删了测试路径
容易被忽略的兼容性细节
unused 依赖准确的类型解析,对 Go module 状态敏感:
- 本地能过、CI 报
undefined: xxx,八成是go.mod没提交,或replace指向了 CI 拉不到的本地路径 - Go 1.21+ 对泛型的解析更细,
unused在不同版本下对泛型类型参数是否“被使用”的判断可能不一致 - 别把
unused和staticcheck同时开又不调优——比如staticcheck的 SA4006(死循环)和unused的变量未使用可能交叉触发,增加误报理解成本
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











