I am playing around with type parameters (generics) using Go 1.18beta1.
Problem
Consider the following snippet:
package main
import (
"fmt"
)
func main() {
foo := &Foo[string, int]{
valueA: "i am a string",
valueB: 123,
}
fmt.Println(foo)
}
type Foo[T1 any, T2 any] struct {
valueA T1
valueB T2
}
func (f *Foo[_,_]) String() string {
return fmt.Sprintf("%v %v", f.valueA, f.valueB)
}
This snippet fails to build with the following error:
<autogenerated>:1: cannot use .this (type *Foo[string,int]) as type *Foo[go.shape.string_0,go.shape.string_0] in argument to (*Foo[go.shape.string_0,go.shape.int_1]).String
I attempted to use _ in the method declaration because of the following statement in the Type Parameters Proposal:
The type parameters listed in a method declaration need not have the same names as the type parameters in the type declaration. In particular, if they are not used by the method, they can be _.
Question
Is the build error above a bug in 1.18beta1 or am I missing something?
Snippet variations that build successfully
Use type parameter names
I can make the code build successfully if I change the String method declaration to the following (replace the _ with actual type parameters):
func (f *Foo[T1,T2]) String() string {
return fmt.Sprintf("%v %v", f.valueA, f.valueB)
}
Single type parameter
I managed to use the _ successfully when only using a single type parameter:
package main
import (
"fmt"
)
func main() {
foo := &Foo[string]{"i am a string"}
fmt.Println(foo)
}
type Foo[T1 any] struct {
value T1
}
func (f *Foo[_]) String() string {
return fmt.Sprintf("%v", f.value)
}
Instantiate Foo with same type for T1 and T2
_ also works in method declaration if Foo is instantiated with the same type (e.g. string for both T1 and T2):
package main
import (
"fmt"
)
func main() {
foo := &Foo[string, string]{
valueA: "i am a string",
valueB: "i am also a string",
}
fmt.Println(foo)
}
type Foo[T1 any, T2 any] struct {
valueA T1
valueB T2
}
func (f *Foo[_,_]) String() string {
return fmt.Sprintf("%v %v", f.valueA, f.valueB)
}