skip to content
Alvin Lucillo

Comparable types

/ 2 min read

Two objects are comparable in Go if their equality can be checked with == or != operations, which only happens if the equality is well-defined. For example, comparing two string values, pointers, or structs:

type S struct {
	name string
}


func main() {
	fmt.Println("a" == "b")

    i := S{}
	j := S{}
	fmt.Println(i == j)

    fmt.Println(&i == &j)

}

We can’t simply compare two maps, functions, or slices with the equality operations because there’s no clear, built-in meaning with them. For example, two slices can refer to different backing array, requiring deep recursive equality. The meaning of equality lies on how we structured those types.

func main() {
	x := []string{}
	y := []string{}

	fmt.Println(x == y) // invalid operation: x == y (slice can only be compared to nil)compilerUndefinedOp
}

There are gotchas.

  1. Two arrays can be compared only if their types and lengths are the same and the types are comparable
  2. Two structs can be compared only if the struct doesn’t have properties that have non-comparable types
type S struct {
	name string
}

type T struct {
	name string
	ages []int
}

func main() {
    // array: can be compared because they have the same type and length
	a := [1]string{"a"}
	b := [1]string{"a"}
	fmt.Println(a == b)

    // array with different length can't be compmared
    c := [2]string{"a", "a"}
	fmt.Println(a == c) // invalid operation: a == c (mismatched types [1]string and [2]string)

    // structs with properties having comparable types
	i := S{}
	j := S{}
	fmt.Println(i == j)

    // structs with properties having non-comparable types can't be compared
	k := T{}
	l := T{}
	fmt.Println(k == l) // invalid operation: k == l (struct containing []int cannot be compared)
}