Go 1.18 Generics 如何使用接口定义一个新的类型参数

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

This 曾经在 go1.18beta1 中有效,但在 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))
}

执行会抛出

./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)

似乎是由于这个限制:

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.

我如何在 go1.18rc1 中执行此操作?

您必须再次将 v 转换回 *M

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

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

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