go - 泛型

为什么要用泛型

go 1.18 前的版本中,如果对传入参数的值不确定时,就要使用空接口的方法传参,然后通过对参数进行断言的方式,取出原结构体。

对泛型切片进行遍历

func printSlice[T any](s []T) {
	for i := 0; i < len(s); i++ {
		fmt.Println(s[i])
	}
}

func main() {
	printSlice[int]([]int{5, 23, 67, 99, 167})
	printSlice([]int{5, 23, 67, 99, 167})                   // 也可以省略参数的形势
	printSlice([]string{"aaa", "bbb", "ccc", "ddd", "eee"}) // 也可以省略参数的形势
}

声明一个泛型切片

type vector[T any] []T //声明泛型切片

func printSlice[T any](s []T) {
	for i := 0; i < len(s); i++ {
		fmt.Println(s[i])
	}
}

func main() {
	v1 := vector[int]{58, 1881}
	printSlice(v1)
	v2 := vector[string]{"烤鸡", "烤鸭", "烤鱼"}
	printSlice(v2)
}

使用 interface 来约束泛型参数

type Num interface {
	~int | ~int8 | ~int32 | ~int64
}

type Str interface {
	string
}

type NumStr interface {
	Num | Str
}

func add[T NumStr](a, b T) T {
	return a + b
}

func main() {
	fmt.Println(add(8, 3))         //都是数值,便对两数值相加
	fmt.Println(add("aaa", "bbb")) //如果都是字符串,就对字符串拼接
	fmt.Println(add(2, "aa"))      //一个是字符串,一个是数值 ~ 报错
}

使用方法来约束

type price int

type showPrice interface {
	String() 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()) //如果传入的类型,没有 string 方法,就会报错
	}
	return
}
func main() {
	fmt.Println(ShowPriceList([]price{1, 2}))
}
posted @ 2022-05-21 17:33  沧海一声笑rush  阅读(130)  评论(0编辑  收藏  举报