deadcode工具是go最直接可靠的死代码检测手段,基于rta算法从main或测试入口追踪调用链,仅报告真正不可达的函数和方法;不支持panic后语句、未用变量或导入包检测。
deadcode 工具是目前最直接、最可靠的 go 死代码检测手段,它能准确识别未被调用的函数和方法,但对 panic 后的不可达语句、未使用的变量或导入包无能为力。
用 deadcode 扫描未被调用的函数和方法
它基于可达性分析(RTA),从 main 函数或测试入口出发,追踪所有可能被执行的函数调用链。只有真正“不可达”的函数才会被报告。
- 必须确保项目中存在
main包,否则会报错:deadcode: no main packages - 默认不扫描测试文件,加
-test参数才包含*_test.go - 输出格式可定制,比如只看文件+函数名:
deadcode -f='{{.Path}}:{{.Name}}' ./ - 用
-whylive=MyFunc可反向追溯该函数为何被判定为“活跃”,帮助验证结果是否合理
go vet 能发现部分死代码,但范围很窄
go vet 仅对明确的控制流中断后仍存在的语句敏感,比如 return、panic、os.Exit 后面的代码。它不会分析跨函数调用关系,也不处理接口实现体是否被实际使用。
- 示例:函数里写
panic("x")后紧跟fmt.Println("dead"),go vet会警告该行不可达 - 但它不会告诉你
Goodbyer.Greet没被任何接口变量赋值过,这种属于deadcode的范畴 - 运行命令:
go vet ./...或针对单个文件:go vet file.go
别指望编译器或 gofmt 帮你揪死代码
Go 编译器默认忽略所有不可达代码,既不报错也不警告——这是设计使然,不是 bug。哪怕 gofmt 或 golint 也完全不涉及此问题。
- 未使用的变量或导入会触发编译错误或
go vet警告,但这和“死函数”是两类问题 -
staticcheck和golangci-lint中的某些检查器(如SA4006)可补全go vet的控制流死代码场景,但依然无法替代deadcode对函数级可达性的判断 - 如果你依赖 CI 自动清理,建议把
deadcode ./ -test作为必检项,而非仅靠go vet
真正容易被忽略的是:deadcode 不分析方法集是否被反射调用、是否被插件式注册(如 flag.Command)、也不管函数是否被 CGO 或 unsafe.Pointer 间接引用——这些都得靠人工确认。工具只负责它能确定的部分。











