Go Generics Erase the Last Excuse for Copy-Pasting Type Variants
Generics eliminate an entire class of repetitive, error-prone boilerplate that Go developers have endured for years. Any team maintaining utility libraries or data structures can now write them once and get compile-time type checking for free, without the performance and safety costs of reflection.
Before Go 1.18, handling multiple numeric or slice types meant copying the same logic for int, float64, and every other variant, or resorting to empty interfaces and reflection, which sacrificed type safety and added runtime panic risks. Generics make the data type itself a parameter, so one function can serve all allowed types.
The core syntax places a type parameter list in square brackets after the function or type name, with a constraint that restricts which concrete types are permitted. Built-in constraints like `any` and `comparable` cover the most common cases, while custom constraints use an interface with a union of types separated by `|`.
Generic structs work the same way, enabling reusable data structures such as stacks and queues that are instantiated for a specific type at compile time. The compiler infers the type argument from the call site, so calling code stays clean.
Go's generics arrive late enough that the community has already internalized the pain of copy-paste type variants; adoption is less about novelty and more about removing a known friction.
The `~` prefix on a type constraint, which the article leaves as an open question, accepts any type whose underlying type is the specified one, making constraints work with named types derived from primitives.
Generic data structures like `Stack[T]` shift Go closer to the ergonomics of languages with long-standing generics, but the constraint system keeps the implementation explicit rather than inferred from structural typing.