泛型类型
泛型类型如何定义?
- 泛型类型: 在类型名后声明类型参数,再让字段使用这些参数;
Stack[int]与Stack[string]是不同的实例化类型;
type Stack[T any] struct {
items []T // 字段类型可使用类型参数
}
泛型类型的方法如何声明? 方法能新增类型参数吗?
- receiver 类型参数: 给泛型类型定义方法时, receiver 必须写成
Stack[T]或*Stack[T]; - 方法类型参数限制: 方法只能使用 receiver 类型已有的类型参数, 不能在方法名后新增
[U any];
// Stack 是泛型类型, 所以方法 receiver 也要写出类型参数 T
func (s *Stack[T]) Push(v T) {
s.items = append(s.items, v)
}
func (s *Stack[T]) Pop() (T, bool) {
var zero T // 获取类型参数 T 的零值
if len(s.items) == 0 {
return zero, false
}
last := len(s.items) - 1
v := s.items[last]
s.items[last] = zero // 清除弹出位置,避免底层数组继续持有引用
s.items = s.items[:last]
return v, true
}
// func (s *Stack[T]) Convert[U any]() U { return *new(U) } // 报错, 方法不能新增自己的类型参数 U
泛型类型如何使用与实例化?
- 实例化: 使用泛型类型时显式给出类型实参;
Stack[int]把内部元素及相关方法参数、结果中的T都确定为int;
func main() {
var s Stack[int] // 用 int 实例化泛型类型
s.Push(10)
v, ok := s.Pop()
println(v, ok)
}
泛型类型如何递归引用自身? 适用于哪些场景?
- 泛型类型递归: 类型声明内部可引用自身的实例化形式;
- 类型实参: 递归引用时需要提供类型参数;
- 使用场景: 链表, 树, 图等递归数据结构;
type Node[T any] struct {
Value T
Next *Node[T] // 递归引用同一类型实参的 Node
}