2021年12月14日 Go 1.18 Beta 1版本发布,带来了大家争议已久的泛型。
已经过去几天了,今天趁周末体验了下go泛型的使用,下面给大家介绍一下,demo是官方提供的。
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-65ed43b8dfff
Administrator@20201002-163950 MINGW64 ~/Desktop
$ go1.18beta1 download
Downloaded 0.0% ( 16384 / 157362450 bytes) ...
Downloaded 5.0% ( 7946192 / 157362450 bytes) ...
Downloaded 20.7% ( 32554768 / 157362450 bytes) ...
Downloaded 36.3% ( 57114192 / 157362450 bytes) ...
Downloaded 51.9% ( 81640864 / 157362450 bytes) ...
Downloaded 67.5% (106282208 / 157362450 bytes) ...
Downloaded 77.3% (121650272 / 157362450 bytes) ...
Downloaded 84.2% (132512784 / 157362450 bytes) ...
Downloaded 99.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.18beta1
Administrator@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是已经为类型参数指定的类型。
mian函数:
在这里调用刚才的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:
SumNumbers:
这个函数的逻辑和前面一样,但是使用的是接口类型作为类型约束,而不是联合类型。main:
这里同样可以在调用泛型函数的时候省略类型参数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))
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)