声明一个泛型函数
package main import "fmt" func printSlice[T any](s []T){ for _,v := range s{ fmt.Printf("%v\n",v) } } func main(){ printSlice[int]([]int{66,77,88,99,100}) printSlice[float64]([]float64{1.1,2.2,5.5}) printSlice[string]([]string{"烤鸡","烤鸭","烤鱼","烤面筋"}) //省略显示类型 printSlice([]int64{55,44,33,22,11}) }
[T any]参数的类型,意思是该函数支持任何T类型;
多个泛型参数语法:
[T, M any]
[T any, M any]
[T any, M comparable]
在调用这个泛型函数的时候,可以显示指定类型参数,
如: printSlice[int]([]int{66,77,88,99,100})
也可以省略显示类型
比如 printSlice([]int64(55,44,33,22,11))
声明一个泛型切片
带有类型参数的类型被叫做泛型类型。下面定义一个底层类型为切片类型的新类型 vector。它是可以存储任何类型的的切片。要使用泛型类型,要先对其进行实例化,就是给类型参数指定一个实参。
package main import "fmt" type vector[T any][]T func printSlice[T any](s []T){ for _,v := range s{ fmt.Printf("%v",v) } } func main(){ v:=vector[int]{58,1881} printSlice(v) v2:=vector[string]{"烤鸡","烤鸭","烤鱼","烤面筋"} printSlice(v2) }
声明一个泛型map
package main import "fmt" type M[K string, V any] map[K]V //这里的K不支持any ,由于底层map不支持,所以使用string func main() { m1 := M[string, int]{"key": 1} m1["key"] = 2 m2 := M[string, string]{"key": "value"} m2["key"] = "new value" fmt.Println(m1, m2) }
声明一个泛型通道
package main import "fmt" type C[T any] chan T func main() { c1 := make(C[int], 10) c1 <- 1 c1 <- 2 c2 := make(C[string], 10) c2 <- "hello" c2 <- "world" fmt.Println(<-c1, <-c2) }
泛型约束
使用interface中规定的类型约束泛型函数的参数
package main import "fmt" type NumStr interface { Num | Str } type Num interface { ~int | ~int8 | ~int16| ~int32| ~int64| ~uint| ~ uint8| ~ uint16| ~ uint32| ~uint64| ~ uintptr| ~ float32| ~ float64| ~ complex64| ~ complex128 } type Str interface { string } func add[T NumStr](a,b T) T { return a + b } func main(){ fmt.Println(add(3,4)) fmt.Println(add("hello","world")) }
上面的 NumStr,新增了类型列表表达式,它是对类型参数进行约束。
使用 | 表示取并集
如果传入参数不在集合限制范围内,就会报错。
使用interface中规定的方法来约束泛型的参数
package main import ( "fmt" "strconv" ) type Price int func (i Price) String() string { return strconv.Itoa(int(i)) } type Price2 string func (i Price2) String() string { return string(i) } type ShowPrice interface { String() string ~int | ~string } func ShowPriceList[T ShowPrice](s []T) (ret []string) { for _, v := range s { ret = append(ret, v.String()) } return } func main() { fmt.Println(ShowPriceList([]Price{1, 2})) fmt.Println(ShowPriceList([]Price2{"a", "b"})) }
使用interface中规定的方法和类型来双重约束泛型的参数
package main import ( "fmt" "strconv" ) type Price int type ShowPrice interface { String() string int | string } func (i Price) String() string { return strconv.Itoa(int(i)) } func ShowPriceList[T ShowPrice](s []T) (ret []string) { for _, v := range s { ret = append(ret, v.String()) } return } func main() { fmt.Println(ShowPriceList([]Price{1, 2})) } //传入浮点参数,就会因为不是约束类型而报错
使用泛型自带comparable约束,判断比较
package main import ( "fmt" ) func findFunc[T comparable](a []T, v T) int { for i, e := range a { if e == v { return i } } return -1 } func main() { fmt.Println(findFunc([]int{1, 2, 3, 4, 5, 6}, 5)) fmt.Println(findFunc([]string{"烤鸡", "烤鸭", "烤鱼", "烤面筋"}, "烤面筋")) }
comparable 的约束类型支持整数 和字符,自定义结构体,也可以嵌套在自定义约束中
type ShowPrice interface { int | string | comparable }
参考文章:http://www.golang.ren/article/193584