Golang comparable built-in type
last modified May 8, 2025
This tutorial explains how to use the comparable built-in type in Go.
We'll cover type constraints with practical examples of using comparable in generics.
The comparable type is a predeclared interface in Go that represents all types that can be compared using == and != operators. It was introduced in Go 1.18 to support generics.
In Go, comparable is used as a type constraint to ensure a type
parameter supports equality operations. This is essential for writing generic
functions that need to compare values.
Basic comparable usage
The simplest use of comparable constrains a type parameter to support
equality operations. This example demonstrates basic comparable usage.
Note: comparable includes all comparable types except interfaces.
package main
import "fmt"
func Equal[T comparable](a, b T) bool {
return a == b
}
func main() {
fmt.Println(Equal(5, 5)) // true
fmt.Println(Equal("foo", "bar")) // false
fmt.Println(Equal(3.14, 3.14)) // true
}
The Equal function works with any comparable type. It demonstrates
how comparable enables type-safe equality comparisons in generics.
Using comparable with structs
Struct types are comparable if all their fields are comparable. This example shows how comparable works with custom struct types.
package main
import "fmt"
type Point struct {
X, Y int
}
func Contains[T comparable](slice []T, value T) bool {
for _, v := range slice {
if v == value {
return true
}
}
return false
}
func main() {
points := []Point{{1, 2}, {3, 4}, {5, 6}}
fmt.Println(Contains(points, Point{3, 4})) // true
fmt.Println(Contains(points, Point{7, 8})) // false
}
The Contains function works with any comparable type, including
structs. The Point struct is comparable because its fields are comparable.
Comparable with maps
Map keys must be comparable types. This example shows how comparable helps create generic map utilities.
package main
import "fmt"
func MapKeys[K comparable, V any](m map[K]V) []K {
keys := make([]K, 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}
func main() {
strMap := map[string]int{"a": 1, "b": 2}
fmt.Println(MapKeys(strMap)) // [a b]
intMap := map[int]string{1: "one", 2: "two"}
fmt.Println(MapKeys(intMap)) // [1 2]
}
The MapKeys function extracts keys from any map type. The K type
parameter must be comparable since map keys require comparison operations.
Comparable limitations
Not all types are comparable. This example demonstrates types that don't satisfy the comparable constraint and how to handle them.
package main
import "fmt"
type NonComparable struct {
Data []int
}
func main() {
// This would cause a compile-time error:
// fmt.Println(Equal(NonComparable{}, NonComparable{}))
// Workaround for non-comparable types
compareSlices := func(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
nc1 := NonComparable{Data: []int{1, 2, 3}}
nc2 := NonComparable{Data: []int{1, 2, 3}}
fmt.Println(compareSlices(nc1.Data, nc2.Data)) // true
}
Slices, maps, and functions are not comparable. The example shows how to work around this limitation with custom comparison logic.
Comparable with interfaces
Interfaces can be comparable if their dynamic types are comparable. This example demonstrates the behavior of comparable with interface types.
package main
import "fmt"
type Stringer interface {
String() string
}
type MyString string
func (ms MyString) String() string {
return string(ms)
}
func CompareStringers[T Stringer](a, b T) bool {
return a == b
}
func main() {
var s1 Stringer = MyString("hello")
var s2 Stringer = MyString("hello")
var s3 Stringer = MyString("world")
fmt.Println(CompareStringers(s1, s2)) // true
fmt.Println(CompareStringers(s1, s3)) // false
}
The CompareStringers function works because the underlying type
(MyString) is comparable. Interface comparisons depend on their dynamic types.
Source
This tutorial covered the comparable built-in type in Go with
practical examples of using it in generic functions and type constraints.
Author
List all Golang tutorials.