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

Bil*_*ose 31 struct types equality go

在阅读了关于在地图中使用切片的相关问题后,我对Go中的平等感到好奇.

我知道可以覆盖equalsJava 的方法Object.是否有类似的方法来定义Go如何检查用户定义的类型/结构是否相等?如果是这样,那么上面提到的问题就会有解决方法.我认为使用interface{}可能会提供解决方案,但我收到了错误消息panic: runtime error: hash of unhashable type []int.

Vol*_*ker 24

不,这不是用户可定义的.Go有严格的规则,即使是可转换的,也可以是可比较的.看一下规范的比较运算符部分.

  • `net.IP`类型有`func(ip IP)Equal(x IP)bool`,它定义了IP地址的等价性.也许这可能是这种方法的典范. (6认同)

AJc*_*dez 19

Go支持等式检查结构.

type Person struct {
    Name string
}

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

a == b // true
Run Code Online (Sandbox Code Playgroud)

它不适用于指针字段(以你想要的方式),因为指针地址是不同的.

type Person struct {
    Friend *Person
}

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

a == b // false
Run Code Online (Sandbox Code Playgroud)

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

import "reflect"

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

reflect.DeepEqual(a, b) // true
Run Code Online (Sandbox Code Playgroud)

请记住,有一些警告.

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

  • 也许“*您无法修改相等运算符,并且没有内置方法来添加对自定义类型的支持以使用 `==` 语法。*”部分应该为只阅读第一句的人标记为粗体。 (4认同)
  • 这不能回答问题。 (2认同)
  • 这不仅没有回答问题,而且使用“reflect.deepequal”的建议具有误导性,并且在许多简单情况下不起作用(例如:当结构字段是一个映射,其中键是另一个结构时)。 (2认同)

kra*_*mir 5

Go 语言本身还没有标准(go 1.13)。

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

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

• 如果值具有形式为的 Equal 方法"(T) Equal(T) bool""(T) Equal(I) bool"whereT可分配给I,则使用x.Equal(y)even ifxy为 nil 的结果。否则,不存在这样的方法,评估继续下一个规则。