← Back to Go Course | Chapter 12: Generics | Lesson 1 of 6

Introduction to Generics

Generics let you write one recipe that works for many different kinds of ingredients, instead of writing a nearly identical recipe for every single ingredient type.

Why Generics?

Before generics, writing a function that worked on both []int and []string meant either duplicating the function per type or falling back to interface{} and losing compile-time type safety. Generics solve this by letting one function definition work across multiple types while the compiler still checks types.

Example: Why Generics?

markup
package main

import "fmt"

func PrintAll[T any](items []T) {
	for _, item := range items {
		fmt.Println(item)
	}
}

func main() {
	PrintAll([]int{1, 2, 3})
	PrintAll([]string{"a", "b"})
}

A Simple Generic Function

A generic function declares one or more type parameters in square brackets right after its name, which can then be used like any other type throughout the function's signature and body.

Example: A Simple Generic Function

markup
package main

import "fmt"

func Max[T int | float64](a, b T) T {
	if a > b {
		return a
	}
	return b
}

func main() {
	fmt.Println(Max(3, 7))
	fmt.Println(Max(2.5, 1.1))
}

Generics Are Still Type-Checked

Even though generic code is written once for many types, Go still fully type-checks each instantiation at compile time -- calling a generic function with a type that doesn't satisfy its constraints is a compile error, not a runtime surprise.

Example: Generics Are Still Type-Checked

markup
package main

import "fmt"

func First[T any](items []T) T {
	return items[0]
}

func main() {
	fmt.Println(First([]string{"go", "generics"}))
	fmt.Println(First([]bool{true, false}))
}
Common Mistakes
  1. Assuming Go had generics from the start -- they were only added in Go 1.18 (2022), so older code and tutorials often avoid them entirely.
  2. Reaching for generics for every function, even when a plain interface or a couple of concrete-typed functions would be simpler.
  3. Forgetting the type parameter must be declared in square brackets before the regular parameter list.
Chapter Summary
  • Generics, added in Go 1.18, let functions and types work with multiple types while staying type-safe.
  • A type parameter is declared in square brackets before the regular parameters, like func Max[T int | float64](a, b T) T.
  • Generics avoid duplicating near-identical code for each concrete type.
  • Go still resolves generic code at compile time -- there's no runtime type-erasure surprise.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.