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.