问题
After reading a related question about using slices in maps, I became curious about equality in Go.
I know it's possible to override the equals method of a Java Object. Is there a similar way to define how Go checks user defined types/structs for equality? If so, there would be a workaround for the issue referenced above. I thought using interface{} values might offer a solution but I received the error message panic: runtime error: hash of unhashable type []int.
回答1:
Go supports equality checking structs.
type Person struct {
Name string
}
a := Person{"Bill DeRose"}
b := Person{"Bill DeRose"}
a == b // true
It won't work with pointer fields (in the way you want) because the pointer addresses are different.
type Person struct {
Friend *Person
}
a := Person{Friend: &Person{}}
b := Person{Friend: &Person{}}
a == b // false
You can't modify the equality operator and there is no built-in way to add support for custom types to use == syntax. Instead you should compare the pointer values using reflect.DeepEqual.
import "reflect"
a := Person{Friend: &Person{}}
b := Person{Friend: &Person{}}
reflect.DeepEqual(a, b) // true
Keep in mind there are caveats.
In general DeepEqual is a recursive relaxation of Go's == operator. However, this idea is impossible to implement without some inconsistency. Specifically, it is possible for a value to be unequal to itself, either because it is of func type (uncomparable in general) or because it is a floating-point NaN value (not equal to itself in floating-point comparison), or because it is an array, struct, or interface containing such a value.
回答2:
No, this is not user-definable. Go has strict rules what counts as equal, and even what is comparable which itself is based on assignability. Take a look at the Comparison operators section of the spec.
回答3:
There's no standard in Go language itself, yet (go 1.13).
However, comparison utilities could provide their own way to support it.
Function cmp.Equal (from google/go-cmp/cmp) supports definition of custom type comparator via definition of a Equal method:
• If the values have an Equal method of the form
"(T) Equal(T) bool"or"(T) Equal(I) bool"whereTis assignable toI, then use the result ofx.Equal(y)even ifxoryis nil. Otherwise, no such method exists and evaluation proceeds to the next rule.
来源:https://stackoverflow.com/questions/20309751/is-it-possible-to-define-equality-for-named-types-structs