无论何时使用参数化类型,包括在内置的make中需要类型参数的任何地方,都必须使用实际类型替换其定义中的类型参数。这就是所谓的实例化。请保留html标记。
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)
推理(Inference)过去在通用的类型中也可以工作,但是有一个限制,即类型参数列表必须非空。然而,这个功能已经被禁用了,因此您必须显式地提供所有类型参数。
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
any
而不需要定义类型:t := make(opStack[any], 0)
,请参见我设置的playground示例中的第10行。 - platypusguyopStack
并在make
中使用它。opStack[any]
也是一个使用any
实例化的别名为interface{}
的类型。 - blackgreen