网络编程
位置:首页>> 网络编程>> Go语言>> Go1.18新特性之泛型使用三步曲(小结)

Go1.18新特性之泛型使用三步曲(小结)

作者:Go学堂  发布时间:2024-05-03 15:05:52 

标签:Go1.18,泛型

01 Go中的泛型是什么

众所周知,Go是一门静态类型的语言。静态类型也就意味着在使用Go语言编程时,所有的变量、函数参数都需要指定具体的类型,同时在编译阶段编译器也会对指定的数据类型进行校验。这也意味着一个函数的输入参数和返回参数都必须要和具体的类型强相关,不能被不同类型的数据结构所复用

泛型就是要解决代码复用和编译期间类型安全检查的问题而生的。这里给出我理解的泛型的定义:

泛型是静态语言中的一种编程方式。这种编程方式可以让算法不再依赖于某个具体的数据类型,而是通过将数据类型进行参数化,以达到算法可复用的目的。

下面,我们通过一个函数的传统编写方式和泛型编写方式先来体验一下。

1.1 传统的函数编写方式

例如,我们有一个函数Max,其功能是计算整型切片中的最大元素,则其传统的编写方式如下:

func Max(s []int) int {
if len(s) == 0 {
return 0
}

max := s[0]
for _, v := range s[1:] {
if v > max {
max = v
}
}

return max
}

m1 := Max([]int{4, -8, 15})

在该示例中,Max函数的输入参数和返回值类型已经被指定都是int类型,不能使用其他类型的切片(例如s []float)。如果想要获取float类型的切片中的最大元素,则需要再写一个函数:

func MaxFloat(s []float) float {
//...
}

传统的编写方式的缺点就是需要针对每一种类型都要编写一个函数,除了函数的参数中的类型不一样,其他逻辑完全一样

接下来我们看看使用泛型的写法。

1.2 泛型函数编写方式

为了能够使编写的程序更具有可复用性,通用编程(Generic programming)也应运而生。使用泛型,函数或类型可以基于类型参数进行定义,并在调用该函数时动态指定具体的类型对其进行实例化,以达到函数或类型可以基于一组定义好的类型都能使用的目的。我们通过泛型将上述Max函数进行改写:

import (
"fmt"
"golang.org/x/exp/constraints"
)

func main() {
m1 := Max[int]([]int{4, -8, 15})
m2 := Max[float64]([]float64{4.1, -8.1, 15.1})

fmt.Println(m1, m2)
}

// 定义泛型函数
func Max[T constraints.Ordered](s []T) T {
var zero T
if len(s) == 0 {
return zero
}
var max T
max = s[0]
for _, v := range s[1:] {
max = v
if v > max {
max = v
}
}

return max
}

由以上示例可知,我们通过使用泛型改写了MaxNumber函数,在main函数中调用MaxNumber时,通过传入一个具体的类型就能复用MaxNumber的代码了。

来源:https://juejin.cn/post/7087951131510308901

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com