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

时间:2013-12-01 07:21:40

标签: types struct go equality

在阅读了关于在地图中使用切片的related question之后,我对Go中的平等感到好奇。

我知道可以覆盖Java equals的{​​{1}}方法。是否有类似的方法来定义Go如何检查用户定义的类型/结构是否相等?如果是这样,那么上面提到的问题就会有解决方法。我认为使用interface{} values可能会提供解决方案,但我收到了错误消息Object

3 个答案:

答案 0 :(得分:17)

不,这不是用户可定义的。 Go有严格的规则,即使是可转换的,也可以是可比较的。看看the Comparison operators section of the spec

答案 1 :(得分:17)

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

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

import "reflect"

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

reflect.DeepEqual(a, b) // true

请记住有警告。

  

一般来说,DeepEqual是Go&#39 ==运算符的递归放宽。但是,如果没有一些不一致的话,这个想法就无法实现。具体来说,一个值可能与自身不相等,要么是因为它是func类型(通常是不可比的),要么是因为它是一个浮点NaN值(在浮点比较中不等于它自己),或者因为它是包含这样一个值的数组,结构或接口。

答案 2 :(得分:0)

Go语言本身尚无标准(进入1.13版)。

但是,比较实用程序可以提供自己的方式来支持它。

函数cmp.Equal(来自google/go-cmp/cmp)通过Equal方法的定义支持自定义类型比较器的定义:

  

•如果值具有"(T) Equal(T) bool""(T) Equal(I) bool"形式的Equal方法,其中T可分配给I,则使用x.Equal(y)的结果即使xy为零。否则,将不存在这种方法,并且评估将继续进行下一条规则。