Go语言 是否使用用户定义的键和用户定义的等式进行Map?

wfveoks0  于 2023-02-27  发布在  Go
关注(0)|答案(2)|浏览(157)

假设我在Go语言中有一个结构体类型,我想用它作为map的键,但是我不想使用Go语言内置的等式运算,那么构建这样一个map的最佳方法是什么呢?
下面是一个具体的例子,我的键类型和相等操作:

type Key struct {
    a *int
}

func Equal(x Key, y Key) bool {
    return *x.a == *y.a
}

如何构建使用Equal进行密钥比较的Map?

qyzbxkaa

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,那么这个示例就不能再被用作哈希键,因为它的标识已经改变了。

lg40wkob

lg40wkob2#

这在Go语言中是不可能的。没有运算符重载或者“Equality”方法可以覆盖(因为没有像你的例子中提到的.NET那样从公共基类继承)。如果你感兴趣的话,这个答案提供了更多关于相等比较的信息;Is it possible to define equality for named types/structs?
正如在评论中提到的,如果你想做这样的工作,我建议使用对象上的属性作为键,你可以根据你如何设置该属性的值来定义相等(就像它可以是对象字节的校验和,或者如果你在寻找成员相等的话)。

相关问题