Generic Methods in Go 1.27 – dominik.info<br>August 20, 2026
When Go 1.18 introduced Generics in 2022, it brought generic type parameters to functions and structs, but left out methods. With the release of Go 1.27, this long-standing limitation has been removed. Methods can now define their own type parameters without adding them to the receiving struct.<br>Why this change was introduced<br>If you want to create a graph node that holds a generic value, you might implement it like this:<br>type Node[T any] struct {<br>value T
Imagine adding a method Map that transforms a node of type T into a node of another type U. Prior to Go 1.27, you were forced to add U directly to the Node struct itself:<br>type Node[T any, U any] struct {<br>value T
func (n *Node[T, U]) Map() Node[T, U] {<br>// ...
Adding U to the struct itself is bad design because U is a type parameter specific to Map. Even though other methods wouldn’t use U, they still had to keep it in their receiver declarations.<br>The only workaround was to implement Map as a package-level function instead of a method, since functions could define their own type parameters. But methods couldn’t, leading to awkward and non-idiomatic code API designs.<br>Starting in Go 1.27, U can be defined exclusively on the Map method:<br>func (n *Node[T]) Map[U any]() Node[U] {<br>// ...
Why did it take so long?<br>The answer lies in how generics are implemented in Go. The compiler handles generics primarily using monomorphization, meaning it will create a copy of generic structs or functions for every specific type they’re used with. Because at some point, the abstract concept of generics needs to be translated to straight-forward machine code.<br>However, Go’s interface system works at runtime. The specific type of a value passed into an interface parameter is resolved while the program runs. This dynamic dispatch clashes with generics being resolved at compile time. Consider what would happen if we wanted to declare our Map method in an interface:<br>type Mapper interface {<br>Map[T any, U any](element T) U
To make this work, the runtime would either need a Just-In-Time compiler to generate machine code for specific types on the fly, or it would need to create said copies for every possible type upfront, resulting in a massively bloated binary.<br>Ultimately, the Go team decided to separate generic methods from interfaces. Go 1.27 allows generic methods on concrete types, but not on interfaces. This distinction is why the above example won’t compile and why the discussions around it took a while.<br>Further Reading<br>Go 1.27 Release Notes (go.dev)<br>Proposal: Generic Methods for Go (GitHub)<br>The Performance of Generics in Go (dominik.info)
Related Posts<br>A Gentle Introduction to Generics in Go<br>The release of generics in Go 1.18 is a major change to the language. How do generics work? How do they impact performance? When do they make sense? A beginner-friendly wrap-up.<br>Go<br>Oct 1, 2022
The Performance of Generics in Go<br>An illumination of the implementation and performance characteristics of Generics in Go.<br>Go<br>Apr 30, 2022