目录

Go 数据结构: map 的键类型约束

结论

键类型不能是以下几种:

  • function

  • map

  • slice

  • 实际类型为functionmapsliceinterface{}

  • 元素类型为functionmapslicearray

  • 元素类型包含functionmapslicestruct

原因

在 Go 语言规范的Map Types部分(原文链接)中规定,在键的值之间必须可以使用操作符==!=,即键的值之间可进行判等操作。

  • function, map, slice这三种类型无法进行判等操作

  • interface{}类型的实际类型如果为上述三者也无法判等

  • array类型若要支持相互比较则要求它的元素类型可相互比较

  • struct类型同理

深层原因

为什么 Go 语言规范要求map的键的值之间可进行判等操作呢?

Go 语言的map类型是一个哈希表的特定实现,每新增一个键-元素对,哈希表便会对键的值进行哈希,而后将键的哈希值真正的键-元素对进行存储。

而当进行查找时,Go 语言会用被查找键的哈希值与已有哈希值逐个对比,如果没有相等的,就会立刻返回结果。如果有相等的,那就需要再用键值本身去对比一次。

为什么还要对比?

因为再厉害的哈希算法,都存在哈希碰撞的可能。所以即使哈希值一样,键值也不一定一样。

如果键类型的值之间无法判断相等,那么当发生哈希碰撞时则无法查找到真正所需的键-元素对了。

只有键的哈希值键值都相等,才能说明找到了所需的键-元素对。


博客更新地址