What type is ‘do not compare’ sentinel in struct definition?
type SomeStruct struct {
_ [0]func() // do not compare
...
}
What exactly is [0]func()? Zero-length slice of func() objects? Something else?
>Solution :
Well, considering my comment might as well be considered an answer:
_ [0]func()
is to be read as an unnamed field of type [0]func(). It’s not a slice but rather an array. A slice would be _ []func. In this case, the array type is of length 0, so effectively an empty type. You can’t store anything in there. This field only serves one purpose:
Because any fields, variables or other names of a function type are by definition incomparable, and as per spec, any struct/type containing a field that cannot be compared becomes overall incomparable. Adding _ [0]func() to any type therefore makes code that does this spit out a compile-time error:
type Base struct {
Foo uint64
}
type SomeStruct struct {
_ [0]func()
Base // embedded
}
func main() {
a, b := Base{Foo: 123}, Base{Foo: 123}
fmt.Println(a == b) // works
safeA, safeB := SomeStruct{Base: a}, SomeStruct{Base: b}
fmt.Println(safeA == safeB) // compiler error
}
Demo here
The reason for using [0]func() rather than func() or []func is that, when the first fields in a struct are of size zero (which we can only know at compile time for an array, not a slice), then they take up 0 bytes in memory. A func() type would not be considered zero bytes in size, so to answer your last question:
Yes, _ [0]func() is used instead of _ func() for optimisation reasons.