Types 是否可以为命名类型/结构定义相等性?

Types 是否可以为命名类型/结构定义相等性?,types,struct,go,equality,Types,Struct,Go,Equality,在阅读了一篇关于在地图中使用切片的文章后,我对Go中的平等性产生了好奇 我知道可以重写Java对象的equals方法。是否有类似的方法来定义Go如何检查用户定义的类型/结构是否相等?如果是这样的话,上述问题将有一个解决办法。我认为使用可能会提供一个解决方案,但我收到了错误消息panic:runtime error:hash of unhable type[]int不,这不是用户定义的。围棋有严格的规则,什么是平等的,甚至什么是可比的,这本身就是基于可转让性。请看。否。您不能修改相等运算符,也没有

在阅读了一篇关于在地图中使用切片的文章后,我对Go中的平等性产生了好奇


我知道可以重写Java
对象的
equals
方法。是否有类似的方法来定义Go如何检查用户定义的类型/结构是否相等?如果是这样的话,上述问题将有一个解决办法。我认为使用可能会提供一个解决方案,但我收到了错误消息
panic:runtime error:hash of unhable type[]int

不,这不是用户定义的。围棋有严格的规则,什么是平等的,甚至什么是可比的,这本身就是基于可转让性。请看。

否。您不能修改相等运算符,也没有内置的方法来添加对自定义类型的支持,以使用
=
语法。相反,您应该使用比较指针值

Go支持相等检查结构

type Person struct {
    Name string
}

a := Person{"Bill DeRose"}
b := Person{"Bill DeRose"}

a == b // true
它无法处理指针字段(按照您希望的方式),因为指针地址不同

type Person struct {
    Friend *Person
}

a := Person{Friend: &Person{}}
b := Person{Friend: &Person{}}

a == b // false


import "reflect"

a := Person{Friend: &Person{}}
b := Person{Friend: &Person{}}

reflect.DeepEqual(a, b) // true
请记住,这里有一些警告

通常,DeepEqual是Go的==运算符的递归松弛。然而,如果没有一些不一致性,这个想法是不可能实现的。具体地说,一个值可能与自身不相等,这可能是因为它是func类型(通常不可编译),也可能是因为它是一个浮点NaN值(在浮点比较中不等于自身),或者是因为它是一个包含此类值的数组、结构或接口


Go语言本身还没有标准(Go1.13)

然而,比较实用程序可以提供自己的方法来支持它

函数(from)通过定义相等方法支持自定义类型比较器的定义:

•如果值具有形式为
“(T)Equal(T)bool”
“(T)Equal(I)bool”
的相等方法,其中
T
可分配给
I
,则使用
x.Equal(y)
的结果,即使
x
y
为零。否则,不存在这样的方法,评估将进入下一个规则


据我所知不是这样。为了解决这个问题,您可以将对象转换为可哈希类型,以便在键中使用,甚至可以使用数组从头开始实现哈希映射。(顺便说一句,一些可能意外的类型是可散列的:指针和成员仅为可散列类型的结构。)下面是“可比较”类型的列表:--令人惊讶的是,包括通道!如果在2019年或更高版本阅读此内容,github.com/google/go-cmp/cmp包中的Equal函数看起来像reflect.DeepEquals,但支持自定义相等函数。对于具有内置相等以外的等价关系的结构,是否有接口或方法名称约定?@kbolino我不知道有这样的约定。
net.IP
类型具有定义IP地址等价性的
func(IP)Equal(x IP)bool
。也许这可以成为这种方法的典范。@kbolino会很好,它会起作用,但它对我不起作用,它对你或任何人起作用吗!这并不能回答问题。可能“您无法修改相等运算符,并且没有内置的方式来添加对自定义类型的支持以使用
==
语法”部分应该用粗体标记,以供仅阅读第一句的人使用。这不仅不能回答问题,使用
reflect.deepequal
的建议具有误导性,在许多简单情况下(例如:当一个结构字段是一个映射,其中键是另一个结构)都不起作用。