一、泛型基本含义
在定义函数(结构等)时候,可能会有多种类型传入。只有在真正使用才知道是什么类型,此时就可以用一个更加宽泛的类型(必须存在一定约束,只能在那些类型的范围内使用)暂时占位。这个类型就叫泛型
写法:[泛型标识 泛型约束] ([T int | float64 | string])
二、通过内置的约束来实现
1、any
使用any约束,实现一个简单的函数
//官网文档解释:any是接口{}的别名,在所有方面等价于接口{},可以匹配所有类型 func same[T any](a, b T) bool { return a == b } func main() { fmt.Println(same(1, 1)) //true fmt.Println(same(1.1, 2.1)) //false fmt.Println(same("1", "10")) //false }
2、comparable
使用 comparable 约束类型。 comparable 是一个编译器内置的特定的扩展接口类型,该类型必须支持“==“ 方法。
//官方文档:comparable是由所有可比类型实现的接口(布尔值、数字、字符串、指针、通道、 //可比类型数组、结构的字段都是可比较的类型)。可比接口只能用作类型参数约束,不是变量的类型。 func Sum[K comparable, V int | float64](m map[K]V) V { var s V for _, v := range m { s += v } return s } func main() { ints := map[string]int{ "first": 34, "second": 12, } floats := map[string]float64{ "first": 35.98, "second": 26.99, } //Ints=46 Floats=62.97 fmt.Printf("Ints=%v Floats=%v\n", Sum(ints), Sum(floats)) }
三、泛型方法
//泛型方法 在方法调用的时候去判断是泛型约束(int|float64|string)里的哪一种 func same[T int | float64 | string](a, b T) bool { return a == b } func main() { //隐式声明 自动转为 same[int](1, 1) fmt.Println(same(1, 1)) //true fmt.Println(same[int](1, 1)) //显式声明 true fmt.Println(same(1.1, 2.1)) //false fmt.Println(same("1", "10")) //false }
四、泛型结构体:
//泛型结构体 结构体声明的就要定义类型 [T any]表示所以类型都接收 type Person[T any] struct { Name string Sex T } func main() { // Person{ // Name string // Sex string // } var p = Person[string]{} p.Name = "linzhonyi" p.Sex = "男" fmt.Println(p) }
五、泛型map:
//泛型map 在TMap创建的时候就要定义K,V的类型 type TMap[K int | string, V int | string] map[K]V func main() { //make(map[string]string) m1 := make(TMap[string, string]) m1["a"] = "a" //make(map[int]string) m2 := make(TMap[int, string]) m2[1] = "a" }
六、泛型切片:
type TSlice[T any] []T func main() { s := make(TSlice[int], 6) s[4] = 123 fmt.Println(s) } 七、创建泛型约束 //创建泛型约束接口 type MyType interface { int | float64 | string | bool | int64 } func test[T MyType](t T) { fmt.Println(t) } func main() { test(111) //111 test("222") //222 test(3.33) //3.33 test(true) //true }
八、~的含义
当定义了自定义类型时正常的泛型接口是无法识别的,需要在泛型接口的类型前加~,表示涵盖底层类型.
//创建泛型约束接口 type MyType interface { ~int | ~float64 } //自定义类型 type MyInt int type MyFloat float64 func test[T MyType](t T) { fmt.Println(t) } func main() { mi := MyInt(111) test(mi) //111 mf := MyFloat(1.11) test(mf) //1.11 }