Generics

Generics in Go (introduced in Go 1.18) allow you to define functions or types that can operate on any data type while maintaining strong type-checking. This eliminates the need for boilerplate code or using the interface{} type, which lacks compile-time safety.

Key Concepts

Type Parameters

func PrintSlice[T any](slice []T) {
    for _, v := range slice {
        fmt.Println(v)
    }
}
  • Generics use type parameters in square brackets [] to specify the types a function or type can accept.

  • Here, T is a type parameter that can represent any type.

Constraints

func Add[T int | float64](a, b T) T {
    return a + b
}
  • Constraints define what operations are allowed on type parameters.

  • Here, T is constrained to int or float64, ensuring the + operator is valid.

any Constraint

  • The any keyword is an alias for interface{} and represents any type without restrictions.

Benefits

  • Compile-Time Safety: The Go compiler enforces type correctness at compile time. Ensures compile-time checks, reducing runtime errors.

  • Monomorphization: For performance, the compiler generates specific versions of generic functions/types for each type used. This avoids runtime overhead.

  • Code Reusability: Avoids duplication of similar functions or data structures.

  • Performance: Unlike interface{}, generics don’t require type assertions or reflection.

Examples

Generic Functions

A function that works with any type

Output:

Generic Types

Define a data structure with type parameters:

Output:

  • In above example we can create a stack that work with any types.

  • This is safer rather than using interface{} because the type is forced in compile time instead of casting it manually in running time.

Multiple Type Parameters

Functions or types with more than one type parameter:

Output:

  • In above example we create a generic map that can accept any type as it values.

  • Note that we use comparable instead of any because map in golang need this to avoids ambiguity, inefficiency, and potential bugs related to mutable or non-comparable types.

New Constraints

Restricting the type parameters with constraints:

Output:

  • In above example we restrict function Sum to only accept Number type that we defined as either int, int64, or float64.

  • If we tried to input string as parameter Sum("A", "B") it will return error:

Last updated