Go 1.27 adds generic methods, allowing a method declaration to define its own type parameters. This extends Go generics beyond generic types and package-level generic functions and makes it easier to organize reusable operations around the type they belong to.
Before Go 1.27, a method could use the type parameters of its receiver type, but it could not introduce new type parameters of its own. Developers often had to move such logic into package-level generic functions.
Generic Method Syntax
func (b Box[T]) Map[U any](fn func(T) U) U {
return fn(b.value)
}
In this example, T belongs to the receiver type Box[T], while U is declared by the method itself.
Generic methods require Go 1.27 or later. They are different from methods on generic types because the method can declare additional type parameters.
Basic Generic Method Example
Example:
package main
import "fmt"
type Box[T any] struct {
value T
}
// Go 1.27: a method may declare its own type parameter.
func (b Box[T]) Map[U any](fn func(T) U) U {
return fn(b.value)
}
func main() {
box := Box[int]{value: 21}
result := box.Map(func(n int) string {
return fmt.Sprintf("Result: %d", n*2)
})
fmt.Println(result)
}
Output:
Result: 42
Why Generic Methods Matter
Generic methods improve API organization. When an operation naturally belongs to a type, it can now stay in that type's method namespace instead of becoming a separate package-level function.
This can make fluent APIs and generic container types easier to read because related behavior is grouped with the receiver.
Generic Methods on Generic Types
A generic receiver and a generic method can use different type parameters.
type Pair[A, B any] struct {
first A
second B
}
func (p Pair[A, B]) TransformFirst[C any](fn func(A) C) C {
return fn(p.first)
}
The receiver uses A and B. The method introduces C for its own result type.
Type Inference
Go can often infer a generic method's type arguments from the values passed to it, just as it does with generic functions.
box := Box[int]{value: 10}
text := box.Map(func(n int) string {
return fmt.Sprintf("%d items", n)
})
The compiler can infer that the method's result type parameter is string from the callback.
Generic Methods and Interfaces
Go 1.27 does not allow interface methods to declare their own type parameters. A generic method also does not directly satisfy an interface method by matching a parameterized signature.
This limitation keeps interface method sets predictable and avoids difficult runtime implementation requirements.
| Feature | Supported in Go 1.27 |
|---|---|
| Generic function | Yes |
| Generic type | Yes |
| Concrete generic method | Yes |
| Interface method with its own type parameters | No |
When to Use Generic Methods
- Use them when a generic operation clearly belongs to a receiver type.
- Use them to reduce package-level helper functions that exist only because older Go versions could not express the method directly.
- Use normal non-generic methods when the operation does not need extra type parameters.
- Keep method type parameters focused so APIs remain easy to understand.
Common Mistakes
- Using an older Go version: generic methods were added in Go 1.27.
- Trying to add type parameters to interface methods: this is not supported.
- Adding generics where one concrete type is enough: generic code should solve a real reuse problem.
- Confusing receiver parameters with method parameters: they are declared in different places and can have different constraints.
Conclusion
Generic methods are one of the most important language additions in Go 1.27. They let methods declare their own type parameters, reduce the need for package-level generic helpers, and make generic APIs easier to organize around the types they operate on.