Generic Functions

Overview

Generic functions use type parameters to work with multiple types while maintaining type safety.

Basic Syntax

func FunctionName[T constraint](params) returnType {
    // body
}

Examples

Map

func Map[T, U any](slice []T, fn func(T) U) []U {
    result := make([]U, len(slice))
    for i, v := range slice {
        result[i] = fn(v)
    }
    return result
}

doubled := Map([]int{1, 2, 3}, func(n int) int { return n * 2 })
// [2, 4, 6]

Filter

func Filter[T any](slice []T, fn func(T) bool) []T {
    var result []T
    for _, v := range slice {
        if fn(v) {
            result = append(result, v)
        }
    }
    return result
}

evens := Filter([]int{1, 2, 3, 4}, func(n int) bool { return n%2 == 0 })
// [2, 4]

Find

func Find[T any](slice []T, fn func(T) bool) (T, bool) {
    for _, v := range slice {
        if fn(v) {
            return v, true
        }
    }
    var zero T
    return zero, false
}

Contains

func Contains[T comparable](slice []T, target T) bool {
    for _, v := range slice {
        if v == target {
            return true
        }
    }
    return false
}

Keys/Values

func Keys[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 Values[K comparable, V any](m map[K]V) []V {
    vals := make([]V, 0, len(m))
    for _, v := range m {
        vals = append(vals, v)
    }
    return vals
}

Type Inference

Go infers type arguments when possible:

// Explicit
result := Map[int, int](nums, double)

// Inferred (preferred)
result := Map(nums, double)

Summary

Pattern Signature
Transform func Map[T, U any]([]T, func(T) U) []U
Filter func Filter[T any]([]T, func(T) bool) []T
Find func Find[T any]([]T, func(T) bool) (T, bool)
Contains func Contains[T comparable]([]T, T) bool