Generic methods
July 28, 2023
Type definitions
…
A generic type may also have methods associated with it. In this case, the method receivers must declare the same number of type parameters as present in the generic type definition.
// The method Len returns the number of elements in the linked list l. func (l *List[T]) Len() int { … }
This probably needs further explanation. Or an example. It did for me.
Let’s look at a simple generic type:
type Thing[T any] struct {
value T
}
Now you might think you could define a method on this type as so:
func (t *Thing) Foo() { ... } // compilation fails: cannot use generic type Thing[T any] without instantiation
But what we’ve just read says this doesn’t work. You must inclue the correct number of type parameters (in this case one) in the method definition:
func (t *Thing[T]) Type() string { // valid
return fmt.Sprintf("%T", t.value)
}
But why? Perhaps to distinguish between a non-generic type of the same name? Nope, that’s invalid…
type Thing[T any] struct {
value T
}
type Thing struct { // compilation fails: Thing redeclared in this block
value any
}
Well, you can actually use the type parameter within the method. Here’s a re-implementation of my earlier Type()
method:
func (t *Thing[T]) Type2() string {
var x T
return fmt.Sprintf("%T", x)
}
See this example on the playground
Quotes from The Go Programming Language Specification Version of December 15, 2022