You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中NaN是否为可比较类型?为何可作为map键使用?

Go中NaN作为map键的行为解析

核心问题解答

  1. NaN属于可比较类型吗?
    float64(以及float32)是Go语言定义的可比较类型,因此可以作为map的键。这不是编译器Bug,完全符合Go语言规范。但需要注意:IEEE 754浮点数标准规定,NaN与任何值(包括自身)的比较结果都是false,这是NaN的特殊特性,也是后续异常行为的根源。

  2. 为什么代码中map的长度最终是2?
    我们逐行分析代码逻辑:

package main

var x = 0.0

func main() {
  var a = x / x // a = NaN,符合IEEE 754标准的计算结果
  var m = map[float64]int{a: 1} // 存入第一个NaN键的条目
  m[a] = 2 // 由于a(NaN)与已有的NaN键比较结果为false,map会新增一个条目而非覆盖
  for k := range m {
    delete(m, k) // 尝试删除遍历到的键,但k是NaN,k == k为false,map无法找到匹配的键,删除操作无效
  }
  println(len(m)) // 两个条目都未被删除,输出2
}
  • 当向map存入NaN键时,由于NaN无法与自身相等,后续使用同一个NaN变量赋值时,map会将其视为新键,导致重复存入。
  • 遍历delete时,因为遍历得到的k是NaN,而map判断键匹配的依据是==比较,k == k结果为false,因此delete操作无法定位到对应的键,自然无法删除任何条目。

总结

Go允许float类型作为map键,NaN作为float的有效值可以被存入,但由于其特殊的比较特性,会导致看似异常的行为——无法通过自身变量覆盖或删除对应的map条目。这是标准规定的特性,而非编译器Bug。

内容的提问来源于stack exchange,提问作者Kushal Billaiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:40:45