When the same operation must work on several types, a generic function lets you write the operation once. Its type parameter appears in square brackets, and a constraint specifies which types are permitted. This can replace duplicated functions or uses of `interface{}` that provide no guardrails over valid input types. section 3.4
Slice processing is a good fit: traversing a slice and appending selected items does not depend on the element type. A callback can supply the type-specific test, leaving the loop reusable. section 3.4.1
Filter integers with one reusable function
```go package main import "fmt" func filter[T any](items []T, keep func(T) bool) []T { var out []T for _, item := range items { if keep(item) { out = append(out, item) } } return out } func main() { nums := []int{1, 2, 3, 4, 5, 6} fmt.Println(filter[int](nums, func(n int) bool { return n%3 == 0 })) } ``` Run it with `go run generic.go` to print `[3 6]`. Here, `any` permits the same filter to work with other element types; the callback decides what to keep. section 3.4.1
Use a narrower constraint when the function itself needs an operation that only selected types support. A `Numeric` interface listing `int8 | int16 | int32 | int64 | float32 | float64` permits one `filterPositive[T Numeric]` function to test `v > 0` for those types. Generic structs are possible too: `Animal[T AnimalType]` can restrict its stored value to a declared union of types. Type arguments can be written explicitly or, in the shown function call, inferred. section 3.4.1 section 3.4
Listing 3.11 A filter function with specific types
type Numeric interface {
int8 | int16 | int32 | int64 | float32 | float64
}
func filterPositive[T Numeric](items []T) []T {
var filtered []T
for _, v := range items {
if v > 0 {
filtered = append(filtered, v)
}
}
return filtered
}
func main() {
ints := []int8{-4,-3,-2,-1,0,1,2,3,4,}
ints = filterPositive[int8](ints)
fmt.Println(ints)
floats := []float32{-4.5,-3.5,-2.5,-1.5,0.5,1.5,2.5,3.5,4.5,}
floats = filterPositive[float32](floats)
fmt.Println(floats)
}
The complete constrained filter applies the same positive-value test to `int8` and `float32` slices. section 3.4.1
Reach for generics when several similar types need the same logic, especially for maps or slices. Ordinary interfaces and type-specific code remain reasonable when they express the task clearly; generics are useful, not obligatory. section 3.4.1 section 3.5



















