跳至主要內容

Go 语言的泛型

逸尘.Lycodx大约 2 分钟后端go泛型

Go语言的泛型

注意

Go 语言从 1.18 开始引入了泛型

一、什么是泛型

从字面上理解”泛“就是广泛,”形“就是类型,可以指广泛的类型;泛型的本质就是参数化类型;总结一下就是:我们不限定他的类型,让调用者自己去定义类型

二、形参与实参

说到泛型就先讲一下形参实参,先看下面的函数

// a 和 b 就是形参
func Add(a int, b int) int {
	return a + b
}

// 1 和 2 就是实参
Add(1, 2)

相关信息

通过上门的函数我们已经知道了形参和实参分别是什么了

我们也能很明显的看出这个方法不是很方便因为它只能计算int类型参数的值,那么有没有一种方法能同时计算多种类型呢?

有人会说:”我直接用interface + 断言不是能解决问题吗?“

能,但是不够优雅

这就要用到泛型

三、Go语言的泛型

3.1 泛型函数

还是以求和的函数为例

func Add[T int | string | float64](a, b T) T {
	return a + b
}

Add[int](1, 2)
Add[string]("aaa", "bbb")
Add[float64](0.618, 3.14)

这里使用T定义类型,用[]去约束类型,这样就能使用我们已经约束了的全部类型

3.2 泛型类型

使用type定义泛型类型

type Slice[T string | int] []T
// 泛型map
type MyMap[KEY int | string, VALUE int | string] map[KEY]VALUE
// 泛型结构体; 可以分别用int string float64去实例化它
type MyStruct[T int | string | float64] struct {
	Id   T
	Name string
}
// 泛型通道
type MyChan[T int | string] chan T

3.3 泛型方法

type MySlice[T int | string | float64] []T

func (s MySlice[T]) Sum() T {
	var total T
	for _, v := range s {
		total += v
	}
	return total
}

// 调用
var m MySlice[int] = []int{1, 23, 4}
m.Sum()

3.4 自定义的泛型类型

func Add[T int | string | float64](a, b T) T {
	return a + b
}

还是看这个Add函数,我们在T里面约束了多种类型了,如果需要更多类型写起来太不优雅了,那怎么办呢?

1)使用Go内置类型

go里面内置了两种类型anycomparable

1671946512426
1671946512426

从源码中我们可以看出any就是interfacecomparable表示go里面所有能比较的类型:int uint float bool struct 指针

2)自定义类型

type MyAddT interface {
	int | string | float64
}

func Add[T MyAddT](a, b T) T {
	return a + b
}

拓展

如果int需要覆盖自定义的int,需要写成~int

总结

泛型的作用其实不广泛,注意是减少重复的代码提高类型安全性

四、参考文档

参考文档:https://go.dev/ref/specopen in new window

友情链接:https://segmentfault.com/a/1190000041634906open in new window

上次编辑于: