I started using Go back around 2015 and was immediately surprised by the lack of a generic type system. Sure, the empty interface{}
existed, but that was hardly the same. At first I thought I wanted needed generics in Go, but over time I began appreciating the simplicity of the language. Therefore I was ambivalent at best when I learned of discussions to introduce generics in Go 2.0, and once the timetable was accelerated to 1.18, I decided it was time to dig into the proposal.
After a while, I gained an appreciation for how generics are implemented with the same elegance as Golang itself, and this moved me to share my experience. Go generics the hard way is a culmination of the time I spent playing with this new feature and provides a hands-on approach to learning all about generics in Go.
- Labs: a hands-on approach to learning Go generics
- FAQ: answers to some of the most frequently asked questions regarding Go generics
- Links: links to related reference material and projects that use generics
- Prerequisites: how to install the prerequisites required to run the examples in this repository
- Hello world: a simple example using generics
- Getting started: an introduction to go generics
- Getting going: basic concepts explored
- Internals: how generics are implemented in golang
- Benchmarks: basic benchmarks for common patterns using generics
- Lessons learned: lessons learned from digging into generics
- How are you using generics in the Go playground?
- What is
T
? - What is this
any
I keep seeing everywhere? - What does the tilde
~
do? - Do Go generics use type erasure?
We can use the Go playground in “Go dev branch” mode to edit and run your program with generics.
The symbol T
is often used when discussing generic types because T
is the first letter of the word type. That is really all there is too it. Just like x
or i
are often the go-to variable names for loops, T
is the go-to symbol for generic types.
For what is worth, K
is often used when there is more than one generic type, ex. T, K
.
The word any
is a new, predeclared identifier and is equivalent to the empty interface in all ways. Simply put, writing and reading any
is just more user friendly than interface{}
😃.
The ~
symbol is used to express that T
may be satisfied by a defined or named type directly or by a type definition that has the same, underlying type as another defined or named type. To learn more about type constraints and the ~
symbol, please refer to the section Tilde ~
.
Generics in Go are not implemented with type erasure. Please jump to Internals for more information.
- Type parameter proposal: the accepted proposal for introdicing generics to go
- Getting started with generics: a tutorial from the authors of go for getting started with generics
- Go language specification: the reference manual for the go language
- Go FAQ: frequently asked questions for go
- Controller-runtime: a write-up and patchset for implementing conditions logic, patch helpers, and simple reconcilers using generics
- Go collections: generic utility functions for dealing with collections in go
- go-generics-example: examples using generics