Go 1.18 Beta 1版本发布泛型
2021年12月14日 Go 1.18 Beta 1版本发布,带来了大家争议已久的泛型。
已经过去几天了,今天趁周末体验了下go泛型的使用,下面给大家介绍一下,demo是官方提供的。
首先要把go的版本升级为Go 1.18 Beta 1
Administrator@20201002-163950 MINGW64 ~/Desktop
$ go get golang.org/dl/go1.18beta1@latest
go: finding golang.org/dl latest
go: downloading golang.org/dl v0.0.0-20211214194107-65ed43b8dfff
go: extracting golang.org/dl v0.0.0-20211214194107-65ed43b8dfffAdministrator@20201002-163950 MINGW64 ~/Desktop
$ go1.18beta1 download
Downloaded0.0% (16384 / 157362450 bytes) ...
Downloaded5.0% (7946192 / 157362450 bytes) ...
Downloaded20.7% ( 32554768 / 157362450 bytes) ...
Downloaded36.3% ( 57114192 / 157362450 bytes) ...
Downloaded51.9% ( 81640864 / 157362450 bytes) ...
Downloaded67.5% (106282208 / 157362450 bytes) ...
Downloaded77.3% (121650272 / 157362450 bytes) ...
Downloaded84.2% (132512784 / 157362450 bytes) ...
Downloaded99.9% (157170528 / 157362450 bytes) ...
Downloaded 100.0% (157362450 / 157362450 bytes)
Unpacking C:\Users\Administrator\sdk\go1.18beta1\go1.18beta1.windows-amd64.zip ...
Success. You may now run 'go1.18beta1'Administrator@20201002-163950 MINGW64 ~/Desktop
$ alias go=go1.18beta1Administrator@20201002-163950 MINGW64 ~/Desktop
$ go version
go version go1.18beta1 windows/amd64
泛型初体验 SumIntsOrFloats函数:
- SumIntsOrFloats这个函数有两个类型形参K和V,还有一个使用类型形参的参数,类型是map[K]V的m。函数的返回值类型是V。
- 方括号内的K参数是什么意思呢?大家都知道map的key对类型有一定要求,所以这里K的类型参数为comparable类型,comparable是在Go中已经声明过的,这个类型是一个可以比较的类型,通俗来讲就是允许使用 == 和 !=进行值比较的类型,comparable接口满足go对map的key的要求。
- V类型参数也指定了一个类型约束,该约束是两种类型的联合:int64和float64,使用|指定两种类型的并集,这样就代表int64和float64都被允许作为V的实参调用这个SumIntsOrFloats函数。
指定m参数的类型为map[K]V,其中K和V是已经为类型参数指定的类型。
- 在这里调用刚才的SumIntsOrFloats函数,首先要传入类型参数,然后再传入实参,调用参数的时候按指定的类型参数将函数内的类型做替换。
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}func main() {
// Initialize a map for the integer values
ints := map[string]int64{
"first": 34,
"second": 12,
} // Initialize a map for the float values
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
} fmt.Printf("Generic Sums111: %v and %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))
}
省略类型参数的写法 大家再来看一下下面的写法,这里调用泛型函数的时候省略了类型参数,这时编译器从函数实参的类型中推断类型参数。
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}func main() {
// Initialize a map for the integer values
ints := map[string]int64{
"first": 34,
"second": 12,
} // Initialize a map for the float values
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
} fmt.Printf("Generic Sums, type parameters inferred: %v and %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))
}
接口类型约束 官方还提供了一个更为简单的约束类型的方法,可以事先声明一种接口类型作为类型约束,这样可以事先多个函数的复用。
Number:
- 这个接口声明了一个int64和float64的联合,当想要类型约束为int64或float64的时候,可以直接使用这个Number类型约束,而不是再写一遍int64 | float64。
- 这个函数的逻辑和前面一样,但是使用的是接口类型作为类型约束,而不是联合类型。
- 这里同样可以在调用泛型函数的时候省略类型参数
type Number interface {
int64 | float64
}func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}func main() {
// Initialize a map for the integer values
ints := map[string]int64{
"first": 34,
"second": 12,
} // Initialize a map for the float values
floats := map[string]float64{
"first": 35.01,
"second": 26.99,
} fmt.Printf("Generic Sums with Constraint: %v and %v\n",
SumNumbers(ints),
SumNumbers(floats))
}
推荐阅读
- Golang|Go 1.18 泛型详解: 从零读懂泛型
- GO语言|Go1.8 泛型简单上手使用
- golang|Go1.18版本泛型详解
- GO学习笔记|go泛型使用方法
- 【第四十三期】社招面经-后端开发 蚂蚁
- 【第十三期】B站后端开发实习生一、二面经
- 【第三十一期】360后台开发实习面经 - 两轮技术面
- golang|golang性能分析工具pprof介绍
- golang|【golang】源码层面学习日志框架logrus 01