Comparison operators
…
Slice, map, and function types are not comparable. However, as a special case, a slice, map, or function value may be compared to the predeclared identifier
nil
. Comparison of pointer, channel, and interface values tonil
is also allowed and follows from the general rules above.
Let’s demonstrate:
var a func()
var b []int
var c map[string]string
fmt.Println(a == nil, b == nil, c == nil) // true, true, true
But this only applies to a direct comparison with nil
. You can’t compare two values together, which might be a bit surprising:
var x func()
var y func()
fmt.Println(x == nil, y == nil) // true, true
fmt.Println(x == y) // invalid operation: x == y (func can only be compared to nil)
Now we’re really done with the discussion of comparisons of different types. Just two more small notes to discuss. First, a small example from the spec on the type of a comparison operator:
const c = 3 < 4 // c is the untyped boolean constant true type MyBool bool var x, y int var ( // The result of a comparison is an untyped boolean. // The usual assignment rules apply. b3 = x == y // b3 has type bool b4 bool = x == y // b4 has type bool b5 MyBool = x == y // b5 has type MyBool )
And finally the promised description of what “strictly comparable” means:
A type is strictly comparable if it is comparable and not an interface type nor composed of interface types. Specifically:
- Boolean, numeric, string, pointer, and channel types are strictly comparable.
- Struct types are strictly comparable if all their field types are strictly comparable.
- Array types are strictly comparable if their array element types are strictly comparable.
- Type parameters are strictly comparable if all types in their type set are strictly comparable.
Quotes from The Go Programming Language Specification Version of August 2, 2023