unused是golangci-lint中负责死代码检测的核心linter,但默认不启用,需在.golangci.yml中显式启用;它能识别未导出的函数、变量等,但默认跳过_test.go文件,且对反射、插件注册等动态调用场景保守不报。

unused 是 golangci-lint 中负责死代码检测的核心 linter,但它默认不启用,且行为与 deadcode(已弃用)不同——它能识别未导出的函数、变量、常量、结构体字段甚至 import,但对测试文件(_test.go)默认跳过,且容易因生成代码或 mock 误报。
为什么 unused 没报你删掉的函数?
常见原因不是配置错,而是根本没启用:
-
unused不在 golangci-lint 默认启用列表里,必须显式写进.golangci.yml的linters.enable中 - 项目用了
go mod,但.golangci.yml不在go.mod同级目录 → 配置不生效 - 配置里写了
disable-all: true却没在enable:下列任何项 →unused被静默关掉 - 目标函数/变量被反射、插件注册或测试调用,但未被静态分析识别 →
unused保守起见不报(这是设计,不是 bug)
如何安全启用 unused 并减少误报?
直接全量启用会扫出大量“合理未用”代码(比如为 future 扩展预留的导出函数),建议分阶段配置:
- 先只开
unused,关掉高噪声兄弟:deadcode(已废弃)、structcheck(字段级检测易误报)、varcheck(全局变量检测太激进) - 排除生成代码目录:
skip-dirs: ["generated", "mocks", "vendor"] - 若项目有大量未导出工具函数,加宽松设置:
unused: check-exported-only: true,只检查导出符号 - CI 中首次启用时加
--fix要谨慎——unused不支持自动删除,只能靠人工确认
unused 在测试文件里为什么还是不工作?
因为 golangci-lint 默认跳过所有 _test.go 文件,哪怕你启用了 unused。要让它检查测试代码,必须同时满足:
立即学习“go语言免费学习笔记(深入)”;
-
run.skip-files清空或移除.*_test\.go正则(不能只依赖--tests参数) -
unused本身不区分测试/非测试上下文,但若测试中用了t.Helper()或require.XXX等间接调用链,它仍可能漏判——这不是配置问题,是静态分析固有限制 - 更现实的做法:把测试逻辑拆到独立的
internal/testutil包里,让unused正常扫描这些辅助函数
真正难处理的不是怎么开 unused,而是怎么判断一个“未使用”的符号到底该删、该导出、还是该加注释说明用途——静态工具给不出这个答案。


















