Code Snippets
/

Go Generics with Type Constraints

Go Generics with Type Constraints

Go 1.18 added generics; Go 1.21 polished them with the new `cmp` and `slices` packages. This snippet shows a generic `Map`, a numeric constraint via `~int | ~float64`, and a `comparable`-bounded set type. The runnable code targets Go 1.18 syntax (no `cmp.Ordered`, no `slices.Sort`) so it compiles on as many Go versions as possible; the 1.21+ shortcuts are referenced in comments. Note: the project's test runner uses Go 1.13.5 which predates generics, so test execution is expected to FAIL there but the code is valid Go 1.18+.

Go
Hard
generics
type-system
go-modules

236 views

3

package main

import "fmt"

// Map applies fn to every element and returns a new slice.
// Type parameters: T is the input element type, U is the output type.
func Map[T, U any](xs []T, fn func(T) U) []U {
    out := make([]U, len(xs))
    for i, x := range xs {
        out[i] = fn(x)
    }
    return out
}

func main() {
    nums := []int{1, 2, 3, 4}
    squares := Map(nums, func(n int) int { return n * n })
    fmt.Println(squares) // [1 4 9 16]

    words := []string{"hello", "world"}
    lengths := Map(words, func(s string) int { return len(s) })
    fmt.Println(lengths) // [5 5]
}

Type parameters appear in square brackets after the function name: [T, U any] introduces two parameters with the loosest possible constraint, any (alias for interface{} since 1.18). The compiler infers concrete types from the arguments at call time, so callers do not need to spell Map[int, int](...) explicitly. make([]U, len(xs)) pre-sizes the result slice for one allocation. This is the Go equivalent of Array.prototype.map in JavaScript or list comprehension in Python; before generics, the only way to write this was per-type duplication or interface{} slices with runtime assertions.

2 more snippets in this entry are available for premium members.

Upgrade to Premium