<返回更多

Go之泛型篇

2023-08-25    程序员技术成长之路
加入收藏

泛型的出现

    泛型是Go语言在1.18版本中才引入的新特性,这是许多开发者期盼已久的一个功能。

所谓泛型,就是在定义函数、接口或数据类型时,不指定具体的类型,而是使用类型占位符(比如 T 或者 any),在实际使用时再指定具体的类型。

简单来说,泛型就是一种在编程时定义函数或数据类型的一种方法,允许它们具有多种数据类型。因此,使用泛型可以更具灵活性地编写代码。

package mAIn
import "fmt"
//定义一个数据类型 Ttype T interface{}
//定义一个泛型函数,该函数接收一个类型为 T 的列表和一个函数,然后返回一个新的列表func Map(t T, f func(T) T) []T {    nt := make([]T, len(t))    for i, v := range t {        nt[i] = f(v)    }    return nt}
func main() {    s := []int{1, 2, 3, 4, 5}    fmt.Println(Map(s, func(i int) int {        return i * i    }))}

在上面的例子中,我们定义了一个泛型函数 Map,它可以接收任何类型的列表和一个函数,然后返回一个新的列表。在 main 函数中,我们传入一个整数列表和一个将整数平方的函数,然后得到一个新的平方列表。

泛型约束

在 Go 1.18 版本引入的泛型特性中,类型参数可使用约束。泛型约束是对泛型参数所能接受的具体类型进行限制的手段,它可以是一个接口或者一个具体的类型。

比如你定义了一个泛型函数, 该函数的参数可以接受任何类型, 但是在函数体内你又需要对这个参数进行加法运算,这种情况下你就需要使用约束将参数类型限制为整型或者浮点型,否则的话不同的数据类型是不能进行运算的。

例如:

type Number interface {  type int, float64}
func Add[T Number](a, b T) T {  return a + b}

在上述例子中,我们定义了一个叫做 Number 的泛型约束,它限制了可以接受的类型为 int 或 float64。然后在 Add 函数中,我们使用了这个约束,所以该函数的参数 a 和 b 必须是 int 或 float64 类型。在函数体内,我们进行了加法运算,因为已经提前通过约束限定了,这里就不会有类型错误。

当然,你也可以使用接口作为约束,限制类型必须实现某些方法。这样就可以在你的泛型函数或者类型中使用这些方法了。约束提高了泛型的灵活性,使其适用于更广泛的场景。

 

泛型推导机制

泛型推导机制(Type Inference)是 Go 1.18 版本引入的一个新特性,主要作用是在调用泛型函数或者使用泛型类型时,可以根据实际传入参数的类型或者上下文环境,自动推导出泛型参数的具体类型。

func PrintSlice[T any](s []T) {    for _, v := range s {        fmt.Println(v)    }}
func main() {    PrintSlice([]int{1, 2, 3})  // 自动推导泛型参数 T 为 int 类型}

在调用 PrintSlice 函数时,我们没有指定泛型参数 T 的具体类型。但是由于我们传入的是一个 int 类型的切片,所以 Go 语言的编译器可以自动推导出泛型参数 T 的具体类型为 int。

这种泛型推导机制极大的提高了代码的简洁性和使用便利性,也是 Go 语言泛型特性的一个重要组成部分。

值得注意的是,虽然大多数情况下 Go 语言可以正确的自动推导出泛型参数的类型,但是在某些复杂的场景下,编译器可能无法正确推导出类型,这时就需要显式的指定泛型参数的类型。

关键词:Go      点击(8)
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多Go相关>>>