Home > Blockchain >  How does 'type DoNotCompare [0]func()' prevent comparability in Golang
How does 'type DoNotCompare [0]func()' prevent comparability in Golang

Time:02-11

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.

  • Related