一、介绍
go在1.18终于加上了泛型。那么在之前,我们都没有用10几年了,一直用。
加上泛型后,到底好处在哪里呢,解决了那些场景的痛点呢?
泛型主要在于归纳,泛型-代表可以多余一种类型。
作为入门的文章,主要介绍两种泛型的使用场景
泛型允许在函数和类型的实现中使用某个类型集合中的任何一种类型。
目前 “类型形参” (type parameters),简称 T
- 面向函数,作为参数
- 面向结构体,作为结构体里面字段的类型
1.1 面向函数,作为参数
我们来看一下,在比较两个数的大小时,没有泛型的时候,仅仅只是传入类型不一样,我们就要再写一份一模一样的函数。
// maxInt64 获取j,j中的最大值
func maxInt64(i, j int64) int64 {
if i >= j {
return i
}
return j
}
// maxInt32 获取j,j中的最大值
func maxInt32(i, j int32) int32 {
if i >= j {
return i
}
return j
}
此时代码的逻辑一样,只是类型不一样,我们可以使用
“类型形参” (type parameters),简称 T
来代表int32
或者int64
。
类型形参type parameters简称T
语法为:
[T int32 | int64]
这样的语法,我们用 类型形参T
来代表int32
或者int64
类型。
上面的
maxInt64(i, j int64) int64
maxInt32(i, j int32) int32
我们使用 类型形参T
来替换为:
func maxInt32orInt62[T int32 | int64](i, j T) T {
if i >= j {
return i
}
return j
}
func TestMaxInt32orInt62(t *testing.T) {
var i1, j1 int32 = 1, 3
t.Log(maxInt32orInt62(i1, j1))
var i2, j2 int64 = 11, 3
t.Log(maxInt32orInt62(i2, j2))
}
输出:
=== RUN TestMaxInt32orInt62
3
11
--- PASS: TestMaxInt32orInt62 (0.00s)
在参数方面 i, j的类型变为T
,以及返回值的类型也是 T
因为我么在前面定义了
[T int32 | int64]
用T来代表int32
或者int64
.
1.2 面向结构体,作为结构体里面字段的类型
我们先看一下正常结构体的写法如下:
type sumInt struct {
Num int64
}
func (s sumInt) Sum() int64 {
return s.Num
}
type sumFloat struct {
Num float64
}
func (s sumFloat) Sum() float64 {
return s.Num
}
func TestSumIntOrFloat(t *testing.T) {
i := sumInt{Num: 100}
t.Log(i.Sum())
f := sumFloat{Num: 100.0}
t.Log(f.Sum())
}
输出:
=== RUN TestSumIntOrFloat
100
100
--- PASS: TestSumIntOrFloat (0.00s)
我们发现Num的类型为int64
或float64
,我们在这里准备用
“类型形参” (type parameters),简称 T
来代替他们。
[T int64 | float64]
修改为如下:
type sumIntOrFloat[T int64 | float64] struct {
Num T
}
func (s sumIntOrFloat[T]) Sum() T {
return s.Num
}
func TestSumIntOrFloat(t *testing.T) {
i := sumIntOrFloat[int64]{Num: 100}
t.Log(i.Sum())
f := sumIntOrFloat[float64]{Num: 100.0}
t.Log(f.Sum())
}
输出:
=== RUN TestSumIntOrFloat
100
100
--- PASS: TestSumIntOrFloat (0.00s)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。