Go 泛型:是否可以嵌入泛型结构?

kri*_*ris 1 generics struct go

我正在写我的硕士论文,并且我正在间接研究 Go 中泛型的“原型”(go2go)。

\n

我想知道是否可以使用组合并嵌入通用结构(当然使用 go2go)?

\n

我想做这样的事情:

\n
type A[T any] struct {\n    a T\n}\n\nfunc (a A[T]) F() T {\n    return a.a\n}\n\ntype B[T any] struct {\n    A[T]\n}\n\nfunc main() {\n    b := B[string]{A[string]{"Hello"}}\n    fmt.Println(b.F())\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我会收到此错误消息,该消息指的是主函数中对 \xe2\x80\x9cPrintln\xe2\x80\x9d 的调用: \xe2\x80\x9ctype B[string] of b does not match A[T] (无法推断 T)\xe2\x80\x9d

\n

其非通用版本可能是这样的(可以工作并打印 \xe2\x80\x9cHello\xe2\x80\x9d):

\n
type A struct {\n    a string\n}\n\nfunc (a A) F() string {\n    return a.a\n}\n\ntype B struct {\n    A\n}\n\nfunc main() {\n    b := B{A{"Hello"}}\n    fmt.Println(b.F())\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我对 Go 中的这个新的通用方面不太熟悉,所以可能是我做错了?或者说这是不可能的?

\n

bla*_*een 5

是的,可以以您提供的形式嵌入通用结构:

// type-parametrized struct
type A[T any] struct {
    a T
}

type B[T any] struct {
    A[T] // embedded
}
Run Code Online (Sandbox Code Playgroud)

您的代码片段在GoTip Playground上运行得很好,与旧的 Playground 不同,GoTip Playground 与 Go master 分支保持同步。(无论如何,Go 1.18 已经发布了测试版)。

请注意,在所有情况下都A必须使用类型实例化,无论是在结构体还是变量声明中:

type B[T any] struct {
    A // cannot use generic type A[T any] without instantiation
}
Run Code Online (Sandbox Code Playgroud)

最后,类型参数不必从嵌入结构继承。所以

type C[T any] struct {
    A[string] // fine
}

type D struct {
    A[string] // fine
}
Run Code Online (Sandbox Code Playgroud)

C在这种情况下,在实例化或类型的变量时D,必须A使用相同类型参数初始化该字段:

c := D{A[string]{"Hello"}}
Run Code Online (Sandbox Code Playgroud)

不可能的是直接嵌入类型参数:

type A[T any] struct {
    T // embedded type param
}
Run Code Online (Sandbox Code Playgroud)

当前的仿制药提案确实表明这应该是可能的:

当泛型类型是结构体并且类型参数作为字段嵌入到结构体中时,字段的名称就是类型参数的名称。

然而,我们决定将其排除在 Go 1.18 之外(来源)。