dictionary - go 的 map 哈希函数如何工作,具有“相同”值的不同类型会导致不同的键?
问题描述
我知道值不一样,所以我双重引用它,我想知道 go 的映射哈希是如何工作的,cusKey
并且a
类型不同导致键不同。
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])
}
输出是
5
6
怎么去实现这个?两个键值都是1
.
我知道如果类型不同,则两个值不同。所以两者1
并不相同。
但实际上 go 的 map 是如何做到的呢?我试图map.go
在源代码中找到,但我找不到在哪里实现散列函数。它是否使用类型注释计算键的哈希?
解决方案
a
并且cusKey
不能相等,因为它们有不同的类型。a
is of type int
,并且cusKey
is of type key
(它具有int
作为其基础类型,但它是不同的类型)。
Go 地图要求键具有可比性。规格:地图类型:
比较运算符
==
和!=
必须为键类型的操作数完全定义
dic
您的地图的关键类型是interface{}
,它是一个接口类型,并且接口值是可比较的,如果Spec: 比较运算符:
- 接口值具有可比性。如果两个接口值具有相同的动态类型和相同的动态值,或者两者都具有值,则它们是相等的
nil
。
接口值存储动态类型和值,示意性地,它是“(值,类型)”对。比较接口值的时候,也会比较类型,如果不匹配,接口值比较会 yield false
。有关接口表示的详细信息,请参阅Go Data Structures: Interfaces (by Russ Cox)。
有关 Go 地图的内部信息,请查看Dave Cheney:Go 运行时如何有效地实现地图(没有泛型)。
推荐阅读
- python-3.x - 日志处理程序的默认级别是什么?
- firebase - 如何在bigquery中计算每个screen_class(firebase)的平均访问时间?
- javascript - 滑动、刷新、布局可以替换为 lambda 错误
- 3dsmax - 如何在 3dsmax 中使用 maxscript 创建工具栏
- vue.js - 更好的 nuxt vuex 工作流程?
- php - 侧边栏中未显示 WordPress 类别 (post-new.php)
- postgresql - Postgres / K8S:PANIC 找不到有效的检查点记录 / CrashLoopBackOff
- sql - Prolog to SQL:有什么方法可以改进单元测试的 SQL 代码并优雅地修复边缘情况?
- google-apps-script - 如何在 Google Apps 脚本中创建搜索栏?
- tensorflow - 无法使用 GradientTape 重现 model.fit