Go 1.18 版本增加了对泛型的支持。泛型是自Go语言开源以来对Go做出的一次最大的变更。
函数和类型新增对**类型形参(type parameters)的支持。
将接口类型定义为类型集合,包括没有方法的接口类型。
支持类型推导,大多数情况下,调用泛型函数时可省略类型实参(type arguments)。
现在,函数和类型被允许拥有类型形参(Type Parameters)。一个类型形参列表看起来和普通的函数形参列表一样,只是它使用的是方括号而不是小括号。语法 :
func 函数名称 [T 类型形参 ](参数 T){}
func 函数名称 [T String|int|... 类型 ](参数 T){}
一个示例( P 函数可以打印多种类型数据 ):
package main
import "fmt"
func P[T string | int](data T) {
fmt.Printf("data: %T\n", data)
println(data)
}
func main() {
P[string]("a")
P[int](11)
// 不支持的类型
// P[float32](1.1)
}
所谓泛型,简单地理解就是广泛的类型。
从函数的参数角度讲,我们在定义一个函数参数时会规范其具体类型,如果参数类型不固定,之前使用 any 和断言来解决(效率一般),有了泛型我们就可以实现参数的动态类化。相对于断言、反射,泛型具备类型安全、高效等优点。
// 定义一个泛型切片类型
type MySlice[T int | string] []T
func main() {
s1 := MySlice[string]{"a", "b", "c"}
fmt.Printf("s1: %v\n", s1)
s2 := MySlice[int]{1, 2, 3}
fmt.Printf("s1: %v\n", s2)
}
package main
import "fmt"
// 定义一个泛型 map
type MyMap[KEY int | string, VALUE float32 | float64] map[KEY]VALUE
func main() {
var m1 MyMap[string, float64] = map[string]float64{"go": 9.9, "java": 9.0}
fmt.Printf("m1: %v\n", m1)
}