# Generics — Go (Golang)

Source: https://www.skillbyai.com/en/go/t-generics

> Type parameters and constraints.

## Write once for many types

Since Go 1.18, functions and types can take **type parameters**: `func Max[T cmp.Ordered](items []T) T` works for any ordered type. **Constraints** (interfaces such as `any`, `comparable`, `cmp.Ordered`) say what operations are allowed. Generic types like `Stack[T]` hold any element type. Use generics for containers and algorithms over many types (the `slices` and `maps` packages are generic); prefer interfaces when you need behaviour rather than type-agnostic data handling.

## Generic functions and a generic stack, run

I ran this with Go 1.27.1 (`go run .` in a module named demo, standard library only). Max works for ints and strings, Map converts ints to strings, and Stack[T] returns the zero value and false when empty.

```go
package main

import (
	"cmp"
	"fmt"
)

func Max[T cmp.Ordered](items []T) T {
	m := items[0]
	for _, v := range items[1:] {
		if v > m {
			m = v
		}
	}
	return m
}

func Map[T, U any](in []T, f func(T) U) []U {
	out := make([]U, 0, len(in))
	for _, v := range in {
		out = append(out, f(v))
	}
	return out
}

type Stack[T any] struct{ items []T }

func (s *Stack[T]) Push(v T) { s.items = append(s.items, v) }
func (s *Stack[T]) Pop() (T, bool) {
	var zero T
	if len(s.items) == 0 {
		return zero, false
	}
	v := s.items[len(s.items)-1]
	s.items = s.items[:len(s.items)-1]
	return v, true
}

func main() {
	fmt.Println(Max([]int{3, 9, 4}), Max([]string{"kiwi", "apple", "mango"}))
	fmt.Println(Map([]int{1, 2, 3}, func(n int) string { return fmt.Sprint(n * n) }))
	var s Stack[string]
	s.Push("a"); s.Push("b")
	v, _ := s.Pop()
	_, ok := (&Stack[int]{}).Pop()
	fmt.Println(v, ok)
}
```

Output:

```
9 mango
[1 4 9]
b false
```

## Reach for slices and maps packages first

Many generic helpers (Contains, Index, Sort, Max, Keys) already exist in the standard library.

**Quiz:** What does the constraint cmp.Ordered allow?

- [x] Types that support < and > comparisons
- [ ] Any type at all
- [ ] Only strings
- [ ] Only types with a String method

*Answer:* Types that support < and > comparisons. Constraints limit type parameters.
