假设我在Go语言中有一个结构体类型,我想用它作为map的键,但是我不想使用Go语言内置的等式运算,那么构建这样一个map的最佳方法是什么呢?下面是一个具体的例子,我的键类型和相等操作:
type Key struct { a *int } func Equal(x Key, y Key) bool { return *x.a == *y.a }
如何构建使用Equal进行密钥比较的Map?
Equal
qyzbxkaa1#
Go语言对Map键的值有严格的语义可比性,因此,你不能像其他语言那样为Map键定义自己的哈希代码和等式函数。但是,请考虑以下解决方法。不要将结构示例直接用作键,而是使用结构的派生属性,该属性本质上可用作键,并且具有所需的相等语义。通常,将整数或字符串值派生为哈希代码(用作示例的标识)很简单。重要的是,只有当键真正代表了所存储值的语义身份时,它们才应该发生冲突,也就是说,对应的值应该真正可以互换。例如:
type Key struct { a *int } func (k *Key) HashKey() int { return *(*k).a } k1, k2 := Key{intPtr(1)}, Key{intPtr(2)} m := map[int]string{} m[k1.HashKey()] = "one" m[k2.HashKey()] = "two" // m = map[int]string{1:"one", 2:"two"} m[k1.HashKey()] // => "one"
当然,不变性是这种方法的一个关键问题,在上面的例子中,如果你修改了字段a,那么这个示例就不能再被用作哈希键,因为它的标识已经改变了。
a
lg40wkob2#
这在Go语言中是不可能的。没有运算符重载或者“Equality”方法可以覆盖(因为没有像你的例子中提到的.NET那样从公共基类继承)。如果你感兴趣的话,这个答案提供了更多关于相等比较的信息;Is it possible to define equality for named types/structs?正如在评论中提到的,如果你想做这样的工作,我建议使用对象上的属性作为键,你可以根据你如何设置该属性的值来定义相等(就像它可以是对象字节的校验和,或者如果你在寻找成员相等的话)。
2条答案
按热度按时间qyzbxkaa1#
Go语言对Map键的值有严格的语义可比性,因此,你不能像其他语言那样为Map键定义自己的哈希代码和等式函数。
但是,请考虑以下解决方法。不要将结构示例直接用作键,而是使用结构的派生属性,该属性本质上可用作键,并且具有所需的相等语义。通常,将整数或字符串值派生为哈希代码(用作示例的标识)很简单。
重要的是,只有当键真正代表了所存储值的语义身份时,它们才应该发生冲突,也就是说,对应的值应该真正可以互换。
例如:
当然,不变性是这种方法的一个关键问题,在上面的例子中,如果你修改了字段
a
,那么这个示例就不能再被用作哈希键,因为它的标识已经改变了。lg40wkob2#
这在Go语言中是不可能的。没有运算符重载或者“Equality”方法可以覆盖(因为没有像你的例子中提到的.NET那样从公共基类继承)。如果你感兴趣的话,这个答案提供了更多关于相等比较的信息;Is it possible to define equality for named types/structs?
正如在评论中提到的,如果你想做这样的工作,我建议使用对象上的属性作为键,你可以根据你如何设置该属性的值来定义相等(就像它可以是对象字节的校验和,或者如果你在寻找成员相等的话)。