Go 泛型尝鲜

我在二月份的文章利好!极大可能在go 1.17中就能尝试泛型提到,虽然Go泛型会在Go 1.18中正式发布,但是因为各种原因,代码已经开始在master分支中实现,所以极大可能你会在今年9月份发布的Go 1.17中就能尝试使用Go泛型。

那么,现在,可以去掉"可能"这两个字了。在Go 1.17可以确定的说你能够尝试Go泛型编程了,尽管建议你还是在Go 1.18以及以后的版本才正式在产品中使用泛型。

即使是现在,你也可以通过自己编译master分支的方式,开始领略Go泛型的风采。

安装

你可以通过下面的命令按照最新的master分支(Go项目中称之为tip):

1
2
go get golang.org/dl/gotip
gotip download

gotip命令会clone最新的master并进行编译,编译完之后,你就是可以使用gotip命令了。在需要go执行程序的时候,只需要换成gotip即可。

如果因为墙或者网络的原因,你不能执行上面的gotip download命令的话,你也可以直接git clone github上的go项目,执行src下的make.bash文件,也可以编译出go可执行程序。

甚至你也可以结合这两种方式,相信如果有些许的下载困难不会阻碍到你。

运行泛型例子

比如下面一个加法的泛型例子,定义了一个Addable的约束(constraint),也就是可以执行加法的类型约束。
然后实现了一个泛型方法add, 参数有两个(a和b),类型是满足Addable约束的类型,然后返回相加的结果。

main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main
import (
"fmt"
)
type Addable interface {
type int, int8, int16, int32, int64,
uint, uint8, uint16, uint32, uint64, uintptr,
float32, float64, complex64, complex128,
string
}
func add[T Addable](a, b T) T {
return a + b
}
func main() {
fmt.Println(add(1,2))
// FIXME
//fmt.Println(add("foo","bar"))
}

运行gotip build -gcflags=-G=3 main.go可以执行这个文件,返回结果3。

Go语言中两个字符串可以相加吗?

"是的"! 字符串相加相当于concat,把两个字符串连接起来,返回一个新的连接的字符串。按说,字符串也满足Addable约束,但是你如果把倒数第二行的注释去掉的话,这个程序是编译不过的。

原因在于Go的泛型还在开发之中,里面肯定还有大大小小的问题,所以即使Go 1.17发布了,必然还得存在一些不完善得地方,更何况现在里发布Go 1.17还早呢。

更多得例子可以参照Yasuhiro Matsumoto的mattn/go-generics-example项目,他提供十几个泛型的例子,包括上面的add的例子。

如果你觉得好玩,不妨按照本文的安装方法,试试Go的泛型的功能。