ProgrammingGo Developer

What data types in Go are considered comparable and what happens when you try to compare incompatible types? How does this affect the use of maps and sets?

Pass interviews with Hintsage AI assistant

Answer

In Go, variables can be compared to each other using the == operator or used as keys in a map only if their type is comparable. The comparable types include:

  • All numeric types (int, float64, ...)
  • Strings (string, rune)
  • Pointers
  • Channels
  • Interfaces, if their values are comparable
  • Arrays and structs, if all their fields are comparable

Slices, maps, functions — are not comparable!

Attempting to compare such values results in a compile-time error. For example:

var a = []int{1,2,3} var b = []int{1,2,3} printf("%v", a==b) // compile error: slice can only be compared to nil

To use a value as a key in a map, it must be comparable. If the type is not compatible, a compile-time error occurs.

Trick Question

"Can two structs be considered comparable if only some of their fields are not comparable?"

Many answer "yes", but this is incorrect. If at least one field of the struct is not comparable (for instance, a slice or a map), the entire struct becomes non-comparable.

Example:

type T struct { A int S []string } var t1, t2 T t1 == t2 // compile error: Slices are not comparable

Examples of real errors due to a lack of understanding of the nuances of the topic


Story

A developer tried to use a slice as a key to a map to cache computation results, which caused a compile-time error. They switched to a string with an explicit serializer — the problem was solved.


Story

When adding a new field (of type slice) to a struct used as a dictionary key, the project suddenly stopped compiling. The reason: the struct became non-comparable, but no one expected that this would propagate into nested structs.


Story

To create a set of structures with slices inside, they attempted to use a map. Without understanding the comparison rules, they encountered many runtime errors when trying to compare elements, but the issue stemmed from being unable to compile with such a key.