golangci-lint 默认不检测浮点数直接比较,需显式启用 staticcheck 的 SA1025 规则;该规则仅在变量明确声明为 float32/float64 且参与 == 比较时触发,不覆盖常量或类型推导模糊场景,属逻辑误用而非类型错误,需结合封装函数与测试双重防护。

golangci-lint 本身不检测浮点数直接比较
它不会报 a == b 这种写法为问题,哪怕 a 和 b 都是 float64。这不是遗漏,而是设计使然:golangci-lint 的核心 linter(如 staticcheck、govet)聚焦于类型安全、死代码、未处理 error 等明确语义缺陷,但“浮点数用 == 比较”被归类为**逻辑误用**,不属于静态类型系统能可靠推断的范畴。
真正起作用的是 staticcheck 的 SA1025 规则
从 staticcheck v2023.1 起,它新增了 SA1025 检查项,专门捕获形如 float64 == float64 或 float32 == float32 的直接相等比较。但它有严格触发条件:
- 两个操作数必须是相同浮点类型(
float64 == float64✅,float64 == 0.3❌,因为字面量是未定类型,常被推导为float32或float64不稳定) - 不能是常量表达式(
3.14 == 3.14不报,因无运行时风险) - 变量需有明确浮点类型声明或来自浮点运算上下文(比如
x := a + b,其中a、b是float64)
示例会触发 SA1025:
var a, b float64 = 0.1, 0.2
if a + b == 0.3 { // ❌ 报 SA1025:direct float equality comparison
...
}
为什么你可能没看到这个警告
常见原因包括:
-
staticcheck未启用:golangci-lint 默认只开govet和errcheck,必须在.golangci.yml中显式加入staticcheck - 配置中禁用了 SA1025:
staticcheck默认开启该规则,但若项目配置里写了disable: ["SA1025"]就会屏蔽 - Go 版本太低:SA1025 在
staticcheckv0.4.0+ 才稳定支持,对应 golangci-lint v1.53+;旧版即使启用了 staticcheck 也看不到 - 变量类型不明确:比如用
var x = 0.1(推导为float64),但y := 0.2(短声明,也推导为float64),再写x == y—— 这种仍可能漏检,因类型推导链不够“硬”
更可靠的防御方式是自定义检查或测试断言
依赖 SA1025 有盲区,实际工程中建议双保险:
- 在 CI 的
golangci-lint run命令后加一道grep -r '\.==.*float' --include='*.go' . || true粗筛可疑模式(不完美但快) - 把浮点比较封装进函数,强制走容差逻辑,例如统一用
floatEqual(a, b, 1e-9),再用unusedlinter 确保没人绕过它直接写== - 在单元测试里对关键浮点逻辑做反例验证:构造已知精度误差的输入,断言直接
==必须失败,而floatEqual必须成功
最麻烦但最彻底的点在于:浮点比较是否该被禁止,取决于业务语义——有些场景(如哈希校验、序列化一致性)确实要求位级相等,这时 == 反而是对的。工具无法替你做这个判断,只能提示你“这里有个需要人工确认的决策点”。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











