Go 1.18泛型如何使用接口定义一个可实例化的类型参数

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

Go 1.18 Generics how to define a new-able type parameter with interface

问题

这个问题是关于Go语言的代码,你想知道如何在go1.18rc1中解决这个问题。根据你提供的代码和错误信息,问题似乎是由于在结构体类型中嵌入了类型参数或类型参数的指针导致的。根据Go 1.18的限制,目前不允许在结构体类型中嵌入类型参数或类型参数的指针,也不允许在接口类型中嵌入类型参数。目前还不清楚这些限制是否会在将来被允许。

如果你想在go1.18rc1中解决这个问题,你可以考虑重新设计你的代码,避免在结构体类型或接口类型中嵌入类型参数或类型参数的指针。你可以尝试使用其他的方法来实现你的需求,例如使用具体的类型而不是类型参数,或者使用接口类型而不是嵌入类型参数。

希望这可以帮助到你!如果你还有其他问题,请随时提问。

英文:

This used to work in go1.18beta1, but not works in go1.18rc1

package main

type A struct{}

func (*A) Hello() {
	println("Hello")
}

func Create[M any, PT interface {
	Hello()
	*M
}](n int) (out []*M) {
	for i := 0; i < n; i++ {
		v := PT(new(M))
		v.Hello()
		out = append(out, v)
	}
	return
}

func main() {
	println(Create[A](2))
}

Execute will throw

./prog.go:16:21: cannot use v (variable of type PT constrained by interface{Hello(); *M}) as type *M in argument to append:
	PT does not implement *M (type *M is pointer to interface, not interface)

Seems due to this limitation:

> Embedding a type parameter, or a pointer to a type parameter, as an unnamed field in a struct type is not permitted. Similarly, embedding a type parameter in an interface type is not permitted. Whether these will ever be permitted is unclear at present.

How can I do this in go1.18rc1 ?

答案1

得分: 4

你必须将 v 转换回 *M

out = append(out, (*M)(v))

你得到的错误是关于可赋值性的。实际上,你问题中的引用并没有禁止在接口中嵌入 指针类型MPT 都是不同的命名类型参数,你不能将一个赋值给另一个而不进行显式转换。

转换是有效的,因为 PT 类型集中的所有类型(只有 *M)都可以转换为 *M

英文:

You have to convert v back to *M again.

out = append(out, (*M)(v))

The error you got is about assignability. In fact the quote in your question doesn't forbid embedding a pointer type in an interface . Both M and PT are different named type parameters and you can't assign one to the other without explicit conversion.

The conversion instead is valid because all types in PT’s type set (only *M) are convertible to *M.

huangapple
  • 本文由 发表于 2022年3月11日 23:15:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/71440697.html
匿名

发表评论

匿名网友

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

确定