基本概念
类型形参、类型实参、类型约束和泛型类型
type Slice[T int|float32|float64 ] []T
类型形参 T
。类型占位符,不表示具体的类型
类型约束 int|float32|float64
。 中间的 |
的意思是告诉编译器,类型形参 T
只可以接收 int
或 float32
或 float64
这三种类型的实参
类型参数列表 T int|float32|float64
泛型类型 type Slice[T int|float32|float64 ] []T
。完整的泛型类型定义
泛型类型实例化
// 这里传入了类型实参int,泛型类型Slice[T]被实例化为具体的类型 Slice[int]
var a Slice[int] = []int{1, 2, 3}
类型实参 Slice[int]
中的 int
泛型Receiver
func (s Slice[T]) Sum() T {
var sum T
for _, value := range s {
sum += value
}
return sum
}
var s Slice[int] = []int{1, 2, 3, 4}
fmt.Println(s.Sum()) // 输出:10
var s2 Slice[float32] = []float32{1.0, 2.0, 3.0, 4.0}
fmt.Println(s2.Sum()) // 输出:10.0
泛型函数
func Add(a int, b int) int {
return a + b
}
func Add[T int|float32|float64](a T, b T) T {
return a + b
}
Add[int](1,2) // 传入类型实参int,计算结果为 3
Add[float32](1.0, 2.0) // 传入类型实参float32, 计算结果为 3.0
Add[string]("hello", "world") // 错误。因为泛型函数Add的类型约束中并不包含string
Go标准库提供的泛型库
slices,maps 库
var list []int{3, 2, 1}
slices.Sort(list) //排序
slices.Reverse(list) //翻转
slices.Contains(list, 1) //是否包含
...
m := map[string]int{
"a": 1,
"b": 2,
"c": 3,
}
maps.Keys(m) //提取 key ["a", "b", "c"]
maps.Values(m) //提取 value [1, 2, 3]
maps.Clone(m) //克隆
...
总结
当你需要针对不同类型书写同样的逻辑,使用泛型来简化代码是最好的 (比如写个队列,写个链表、栈、堆之类的数据结构)
https://segmentfault.com/a/1190000041634906#item-2