go 的 map 哈希函数如何工作,具有“相同”值的不同类型会导致不同的键?

Li *_*yao 4 dictionary hashmap go

我知道这个值是不相同的,所以我双qouted它,我想知道的是Go的地图散列是如何工作的,这样cusKeya在类型的结果不同的关键是不同的。

package main

import (
    "fmt"
)

type key int

const cusKey key = 1
const a int = 1


func main() {
    dic := make(map[interface{}]interface{})
    dic[cusKey] = 5
    dic[a] = 6
    fmt.Println(dic[cusKey])
    fmt.Println(dic[a])
}

Run Code Online (Sandbox Code Playgroud)

输出是

5
6
Run Code Online (Sandbox Code Playgroud)

如何实现这一目标?这两个键值都是1.

我知道如果类型不同,则两个值不同。所以两者1并不相同。

但实际上 go 的地图是如何做到的呢?我试图map.go在源代码中找到,但我找不到在哪里实现哈希函数。它是否使用类型注释计算键的哈希?

icz*_*cza 11

a并且cusKey不能相等,因为它们具有不同的类型。ais of type int,并且cusKeyis of type key(它具有int作为其基础类型,但它是一种不同的类型)。

Go 地图要求键具有可比性。规格:地图类型:

比较运算符 ==!=必须为键类型的操作数被完全定义

你的dic地图的键类型是interface{},它是一种接口类型,如果Spec:Comparison 运算符,则接口值是可比较的:

  • 接口值具有可比性。如果两个接口值具有相同的动态类型和相同的动态值,或者两者都具有 value,则它们相等nil

接口值存储动态类型和值,示意性地,它是一个“(值,类型)”对。比较接口值时,也会比较类型,如果不匹配,则接口值比较会产生false。有关接口表示的详细信息,请参阅Go Data Structures: Interfaces (by Russ Cox)

有关 Go 地图的内部信息,请查看Dave Cheney:Go 运行时如何有效地实现地图(没有泛型)


Adr*_*ian 7

键的类型为interface{}。Go 中的接口值有两个字段:底层值的类型描述符和指向值本身的指针。因此,具有不同底层类型的两个接口值不相等,即使底层值被认为是相等的。