Per protobuf pragma
`type DoNotCompare [0]func()` DoNotCompare can be embedded in a struct to prevent comparability
I am confused why DoNotCompare
could prevent comparability, and try to understand with the following codes. Unfortunately, I am failed. The NonCompare
struct seems could be comparability.
type DoNotCompare [0]func()
type NonCompare struct {
DoNotCompare
ii int8
}
type Comparer interface {
Compare(b NonCompare) int
}
func (a NonCompare) Compare(b NonCompare) int {
if a.ii > b.ii {
return 1
}
return 0
}
func main() {
var nc1 = NonCompare{ii: 3}
var nc2 = NonCompare{ii: 5}
nc1.Compare(nc2)
Is there anything am I missing?
CodePudding user response:
The prevention works on the builtin ==
operator, not on what your Compare()
method does. Of course it can do whatever you want it to.
But if you try to use ==
:
fmt.Println(nc1 == nc2)
You get a compile-time error:
./prog.go:30:18: invalid operation: nc1 == nc2 (struct containing DoNotCompare cannot be compared)
The reason is because values of func()
type (or any function type) are not comparable, so [0]func()
values are also not comparable. And structs having a field of a non-comparable type are also not comparable. Rules are listed at Spec: Comparison operators:
The equality operators == and != apply to operands that are comparable. The ordering operators <, <=, >, and >= apply to operands that are ordered. These terms and the result of the comparisons are defined as follows:
- [...]
- Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
- Array values are comparable if values of the array element type are comparable. Two array values are equal if their corresponding elements are equal.
[...] Slice, map, and function values are not comparable.
An array of size 0
is used so the field's size will be 0, not adding anything extra to the struct it is used in. Please note this is only guaranteed if you place 0-size fields to the first place. For details see Struct has different size if the field order is different.