Go泛型
泛型function
// type any = interface{}
// [T any]为类型约束,any 表示任意类型,(s []T)为参数。
func printSlice[T any](s []T) {
for _, v := range s {
fmt.Printf("%v ", v)
}
fmt.Println()
}
func main() {
printSlice([]int{1, 2, 3, 4, 5}) //1 2 3 4 5
printSlice([]float64{1.1, 2.2, 3.3, 4.4, 5.5}) //1.1 2.2 3.3 4.4 5.5
printSlice([]string{"hello ", "world"}) //hello world
}
泛型slice
type vector[T any] []T
func main() {
vI := vector[int]{1, 2, 3}
vS := vector[string]{"hello", "world"}
fmt.Println(vI) //[1 2 3]
fmt.Println(vS) //[hello world]
}
泛型map
type M map[string]any
type H[K string, V any] map[K]V
func main() {
m := make(M)
m["String"] = "hello"
m["Int"] = 123
m["float"] = []float64{
1.1,
2.2,
3.3,
}
fmt.Println(m) //map[Int:123 String:hello float:[1.1 2.2 3.3]]
//另一种写法
h := H[string, string]{
"hello": "world",
}
h2 := H[string, int]{
"test": 123,
}
fmt.Println(h) //map[hello:world]
fmt.Println(h2) //map[test:123]
}
泛型channel
type C chan any
type N[T any] chan any
func main() {
ch := make(C, 2)
ch <- "hello"
ch <- 123
fmt.Println(<-ch) //hello
fmt.Println(<-ch) //123
//另一种写法
n := make(N[int], 1)
n <- 123
fmt.Println(<-n) ///123
n2 := make(N[string], 1)
n2 <- "world"
fmt.Println(<-n2) //world
}
泛型(类型)约束
type Num interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~float32 | ~float64
// ~ 代表底层数据类型
}
type Str interface {
string
}
type NumStr interface {
Num | Str
}
func main() {
fmt.Println(add(10, 20)) //30
//fmt.Println(add(1.1, 2.2)) //3.3000000000000003
fmt.Printf("%.1f\n", add(1.1, 2.2)) //3.3
fmt.Println(add("hello", " world")) //hello world
}
func add[T NumStr](a, b T) T {
return a + b
}
泛型(方法)约束
type Price int
type ShowPrice interface {
String() string
}
func (p Price) String() string {
return strconv.Itoa(int(p))
}
func ShowPriceList[T ShowPrice](s []T) []string {
var res []string
for _, v := range s {
res = append(res, v.String())
}
return res
}
func main() {
fmt.Println(ShowPriceList([]Price{1, 2, 3, 4, 5})) //[1 2 3 4 5]
}
泛型(类型 方法)约束
type IPrice int
type SPrice string
type ShowPrice2 interface {
String() string
~int | ~string //如果使用 ~int | string 报错 无法将 SPrice 用作类型 ShowPrice2 类型未实现约束 'ShowPrice2',因为类型未包括在类型集('~int', 'string')中
// ~ 代表底层数据类型
}
func (i IPrice) String() string {
return strconv.Itoa(int(i))
}
func (s SPrice) String() string {
return string(s)
}
func ShowPriceList2[T ShowPrice2](s []T) []string {
var res []string
for _, v := range s {
res = append(res, v.String())
}
return res
}
func main() {
fmt.Println(ShowPriceList2([]IPrice{1, 2, 3, 4, 5})) //[1 2 3 4 5]
fmt.Println(ShowPriceList2([]SPrice{"hello", "world"})) //[hello world]
}
泛型comparable
func findIndex[T comparable](s []T, t T) int {
for i, v := range s {
if v == t {
return i
}
}
return -1
}
func main() {
fmt.Println(findIndex([]int{1, 2, 3, 4, 5}, 3)) //2
fmt.Println(findIndex([]string{"hello", "apple", "world"}, "apple")) //1
}
//Comparable是由所有可比类型实现的接口
//(布尔值、数字、字符串、指针、通道、可比类型数组、
//其字段都是可比类型的结构体)。
//可比接口只能用作类型参数约束,
//而不是变量的类型。
// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.