Description
As part of adding generics, Go 1.18 introduces a new predeclared interface type comparable
. That interface type is implemented by any non-interface type that is comparable, and by any interface type that is or embeds comparable
. Comparable non-interface types are numeric, string, boolean, pointer, and channel types, structs all of whose field types are comparable, and arrays whose element types are comparable. Slice, map, and function types are not comparable.
In Go, interface types are comparable in the sense that they can be compared with the ==
and !=
operators. However, interface types do not in general implement the predeclared interface type comparable
. An interface type only implements comparable
if it is or embeds comparable
.
Developing this distinction between the predeclared type comparable
and the general language notion of comparable has been confusing; see #50646. The distinction makes it hard to write certain kinds of generic code; see #51257.
For a specific example, you can today write a generic Set
type of some specific (comparable) element type and write functions that work on sets of any element type:
type Set[E comparable] map[E]bool
func Union[E comparable](s1, s2 Set[E]) Set[E] { ... }
But there is no way today to instantiate this Set
type to create a general set that works for any (comparable) value. That is, you can't write Set[any]
, because any
does not satisfy the constraint comparable
. You can get a very similar effect by writing map[any]bool
, but then all the functions like Union
have to be written anew for this new version.
We can reduce this kind of problem by permitting comparable
to be an ordinary type. It then becomes possible to write Set[comparable]
.
As an ordinary type, comparable
would be an interface type that is implemented by any comparable type.
- Any comparable non-interface type could be assigned to a variable of type
comparable
. - A value of an interface type that is or embeds
comparable
could be assigned to a variable of typecomparable
. - A type assertion to
comparable
, as inx.(comparable)
, would succeed if the dynamic type ofx
is a comparable type. - Similarly for a type switch
case comparable
.