Go错误:没有示例化就不能使用泛型类型

x6yk4ghg  于 2023-06-03  发布在  Go
关注(0)|答案(3)|浏览(169)

在学习Go泛型时,我遇到了一个似乎无法解决的错误。我把它归结为最简单的代码:

type opStack[T any] []T

func main() {

    t := make(opStack)
    //  t := new(opStack)
    t = append(t, 0)
    fmt.Println(t[0])
}

在playground中,这会在make()调用时发生错误(在被注解掉的new调用时也是如此),并显示以下错误消息:
没有示例化,无法使用泛型类型opStack[T any]
但是make()是一个示例化函数。所以,我想我错过了一些语法上的微妙之处。Go在抱怨什么,需要纠正什么?

pcww981p

pcww981p1#

无论何时使用参数化类型,包括需要类型参数的任何地方,如内置的make,都必须将其定义中的类型参数替换为实际类型。这称为示例化。

t := make(opStack[int], 0)
t = append(t, 0)

如果你将泛型类型用作 * 另一个 * 泛型类型的类型参数,它也必须被示例化:

type Data[T any] struct {
    data T
}

d := Data[opStack[int]]{ data: []int{0, 1, 2} }

您可以使用类型参数示例化,例如在函数签名,字段和类型定义中:

type FooBar[T any] struct {
    ops opStack[T]
}

type OpsMap[T any] map[string]opStack[T]

func echo[T any](ops opStack[T]) opStack[T] { return ops }

语言规范中的相关引用(目前)在两个不同的地方,类型定义:
如果类型定义指定了类型参数,则类型名称表示泛型类型。泛型类型在使用时必须示例化
和示例化
泛型函数或类型通过用类型实参替换类型形参来示例化。[...]
在其他编程语言中,“示例化”可以指创建对象的示例-在Go中,该术语具体指用具体类型替换类型参数。在我看来,这个术语的用法仍然是一致的,尽管在Go中它不一定意味着分配。
请注意,您可以在没有显式类型参数的情况下调用泛型函数。示例化也发生在那里,简单地说,类型参数可能都是从函数参数推断出来的:

func Print[T, U any](v T, w U) { /* ... */ }

Print("foo", 4.5) // T is inferred from "foo", U from 4.5

推理过去也适用于泛型 * 类型 *,但有一个限制,即类型参数列表必须是非空的。但是,此功能已被禁用,因此您必须显式提供所有类型参数。

type Vector[T any] []T 
// v := Vector[int]{} -> must supply T

type Matrix[T any, U ~[]T] []U 
// m := Matrix[int, []int]{} -> must supply T and U
kh212irz

kh212irz2#

因为你想
t = append(t,0)
数据类型可以是int或float group。
这段代码应该能用

package main

import "fmt"

func main() {
    type opStack[T any] []T

    t := make(opStack[int], 0) // You must initialize data type here
    t = append(t, 0)
    fmt.Println(t[0])
}
kulphzqa

kulphzqa3#

谢谢你的详细解释。我试图找到一个相关问题的答案,即如何使用泛型Go Structural typing with Generics处理struct typing。我找到了这样做的方法,认为它可能对类似的情况有所帮助。

package main

type Queue[T any] struct {
}

// Get implements Ops.
func (*Queue[T]) Get() T {
    panic("unimplemented")
}

type Ops[T any] interface {
    Get() T
}

var _ Ops[any] = new(Queue[any])

相关问题