go 泛型终于在大众的呼唤下来了,虽然个人感觉实现的不是那么优雅,但好歹来了不是,那么具体如何使用泛型呢?下面就以官方的示例来讲解下。

就以我们初学代码时经常写的一个函数来说,打算用 map[string]int 来保存数据,需要有个函数能够对 map[string]int 进行汇总加和。

很容易能写出这个代码:

然后我们又来一个需求,需要对 map[string]float32 来做汇总加和,那又需要写一个代码:

后面如果再来一个 float64 呢?有需要有一个函数,这就是我们在写 go 代码时经常会遇到的问题,而泛型能够很好地解决这个问题。

如果熟悉 java 的同学可能知道,java 的泛型使用<>来标识,而 go 的泛型却使用 []来标识,所以要注意。那么上面的实现,如果用 go 的泛型该如何做呢?

首先是利用 go 的 interface 来定义泛型类型 Number ,然后在函数名后紧跟[泛型列表],这里 comparable 是内置的泛型列表,代表所有可比较类型, V 代表所有 Number 类型。这样我们就可以使用时直接指定泛型类型即可调用:

可以看到编辑器给我一个提示,这个提示是说使用时可以不指定泛型类型,直接省略即可

但是需要注意,这并不是总是可以省略的,当你要调用的是一个没有参数的泛型函数时,就不能省略,如下图,可以看到第一个会出错,而第二个则是可以的。

以上就是 go 简单的泛型示例,可以看到支持的还比较简单,估计是设计者并不希望使用者滥用泛型吧,另外为了简化代码编写,go 还加了一个新的类型 any 就是 interface{}。简化使用吧算是。

并且还在 constraints package – golang.org/x/exp/constraints – pkg.go.dev 为我们预先定义了许多类型例如 Integer Ordered 等可以直接使用。

参考文档:

Tutorial: Getting started with generics – The Go Programming Language