-
Notifications
You must be signed in to change notification settings - Fork 18.9k
Description
Go, effectively, has three-kinds of comparability:
- incomparable, there is no
==operator defined for a type (structs and arrays with incomparable fields). - 0-comparable, there is an
==operator but it can only test against the zero value (funcs, maps, and slices can be compared againstnil). The spec treats these as incomparable types and notes the special case. - comparable, there is an
==operator and it works for all values
When writing code with known types, this is not an issue. You know if there's an == operator and whether you can compare against all values or just the zero value.
When generating code (or, possibly in the future, writing generic code) over arbitrary types, this asymmetry is a bit more bothersome. You can't just classify types as comparable or incomparable, you need to handle the 0-comparable case as well even though it is so similar: https://play.golang.org/p/JOmxaVJoYtT
I propose collapsing incomparable and 0-comparable. Allow incomparable structs and arrays to be compared to their zero value. There would always be an == operator and it would always be safe to compare any value to zero. Care would still need to be taken to ensure comparability when using == between arbitrary values, but the simpler classification eases matters.
I believe this would be a 100% backwards-compatible change and perhaps even simplify the spec a bit (or at least not require too many changes).
The concerns would be go/types and reflect, but they both seem to lump what I call 0-comparability in with incomparability, but there, admittedly, could be subtler implications.
This is tangentially related to defining a universal zero value #19642 (comment) in that similar arguments are involved and the two would compliment each other.