"Cannot use .this" error when using _ for multiple type parameters in method declaration

huangapple go评论75阅读模式
英文:

"Cannot use .this" error when using _ for multiple type parameters in method declaration

问题

我正在使用Go 1.18beta1版本尝试使用类型参数(泛型)进行实验。

问题

考虑以下代码片段:

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)
}

这段代码在构建时出现以下错误:

<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

我尝试在方法声明中使用_,是因为在类型参数提案中有以下说明:

方法声明中列出的类型参数不需要与类型声明中的类型参数具有相同的名称。特别是,如果它们在方法中没有使用,可以使用_代替。

问题

上述构建错误是1.18beta1中的错误还是我遗漏了什么?

成功构建的代码片段变体

使用类型参数名称

如果我将String方法声明更改为以下内容(将_替换为实际的类型参数),则代码可以成功构建:

func (f *Foo[T1,T2]) String() string {
	return fmt.Sprintf("%v %v", f.valueA, f.valueB)
}

单个类型参数

当只使用单个类型参数时,我成功地使用了_

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)
}

使用相同类型实例化Foo的T1和T2

如果使用相同类型(例如string)实例化Foo,则方法声明中的_也可以工作:

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)
}
英文:

I am playing around with type parameters (generics) using Go 1.18beta1.

Problem

Consider the following snippet:

package main

import (
	&quot;fmt&quot;
)

func main() {
	foo := &amp;Foo[string, int]{
		valueA: &quot;i am a string&quot;,
		valueB: 123,
	}
	fmt.Println(foo)
}

type Foo[T1 any, T2 any] struct {
	valueA T1
	valueB T2
}

func (f *Foo[_,_]) String() string {
	return fmt.Sprintf(&quot;%v %v&quot;, f.valueA, f.valueB)
}

This snippet fails to build with the following error:

&lt;autogenerated&gt;: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(&quot;%v %v&quot;, f.valueA, f.valueB)
}

Single type parameter

I managed to use the _ successfully when only using a single type parameter:

package main

import (
	&quot;fmt&quot;
)

func main() {
	foo := &amp;Foo[string]{&quot;i am a string&quot;}

	fmt.Println(foo)
}

type Foo[T1 any] struct {
	value T1
}

func (f *Foo[_]) String() string {
	return fmt.Sprintf(&quot;%v&quot;, 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 (
	&quot;fmt&quot;
)

func main() {
	foo := &amp;Foo[string, string]{
		valueA: &quot;i am a string&quot;,
		valueB: &quot;i am also a string&quot;,
	}
	fmt.Println(foo)
}

type Foo[T1 any, T2 any] struct {
	valueA T1
	valueB T2
}

func (f *Foo[_,_]) String() string {
	return fmt.Sprintf(&quot;%v %v&quot;, f.valueA, f.valueB)
}

答案1

得分: 3

根据问题的评论中提到的,所描述的行为是 Go 1.18beta1 中的一个错误,并且正在通过 issue 50419 进行跟踪。

编辑

我确认所讨论的错误已在 1.18beta2 中修复,该版本于2022年1月31日发布。

英文:

As mentioned in the comments of the question, the described behavior is a bug in Go 1.18beta1 and is being tracked by issue 50419.

Edit

I have confirmed that the bug in question is fixed in 1.18beta2, which was released on 31 January, 2022.

huangapple
  • 本文由 发表于 2022年1月4日 07:59:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/70572713.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定