Golang 泛型

5,702次阅读
没有评论

共计 1527 个字符,预计需要花费 4 分钟才能阅读完成。

2022 年 3 月 15 日,争议非常大但同时也备受期待的泛型终于伴随着 Go1.18 发布了。

平时对于版本更新都是漠不关心的,只是近几个月关于泛型的讨论呼声越来越高,于是也来学习一下。

在开始之前,请先将你的 Go 升级到 1.18 及以上的版本

1. 假设有一个求和的函数

我们先在当前目录运行 go mod init 命令,为其提供新代码的模块路径

go mod init test 
go: creating new go.mod: module test
go: to add module requirements and sums:
        go mod tidy

在当前目录新建一个 main.go 文件

那么在早期的版本你可能会这样写

func Add(num map[string]int64) int64 {var ret int64
    for _, v := range num {ret += v}
    return ret
}

在这段代码中:

我们声明了一个 map,从中循环取值累加并返回总和

那么调用的语句如下

func main() {InitNum := map[string]int64{"First":  10,
    "Second": 20,
    "Third":30,
  }
  fmt.Printf("Sum of all number is:%v",Add(InitNum))
}

在终端中输入 go run main.go,运行代码

$ go run main.go
Sum of all number is:60

2. 如果我们想要对不同类型的参数求和呢?

你可能会想到:那我把参数的类型修改下,多搞几个函数一一对应就好了

例如下面这样:

func Add1(num map[string]int64) int64 {var ret int64
  for _, v := range num {ret += v}
  return ret
}
​
func Add2(num map[string]float64) float64 {var ret float64
  for _, v := range num {ret += v}
  return ret
}

但是这样修改就有个问题:用起来太麻烦了,每想要一个新类型就要新生成一个对应类型的函数

泛型就能够很好解决上述问题

3. 添加泛型来处理多种类型

还是上面那个求和的案例,如果使用泛型,我们可以这么写:

func SumIntOrFloat[K comparable, V int64 | float64](m map[K]V) V {var s V
    for _, v := range m {s += v}
    return s
}
  • [] 中声明了两个类型参数 K 和 V,m 类型为 map[K]V。该函数返回一个类型为 V 的值。
  • comparable 是 golang 新引入的预定义标识符,它允许任何类型的值可以用作比较运算符 == 和 !=
  • int64 和 float64。使用 | 指定两种类型的联合,这意味着此约束允许任何一种类型。编译器将允许任一类型作为调用代码中的参数。

那么我们就可以很愉快的用不同类型的参数去调用这个求和函数

func main() {IntNum := map[string]int64{"First":  10,
    "Second": 20,
    "Third":30,
  }
  FloatNum := map[string]float64{"First":  10,
    "Second": 20,
    "Third":30,
  }
​
  fmt.Printf("Sum of all int number is:%v n", SumIntOrFloat(IntNum))
  fmt.Printf("Sum of all float number is:%v", SumIntOrFloat(FloatNum))
}

在终端中执行,输出结果为:

$ go run .
Sum of all int number is:60 
Sum of all float number is:60

原文地址: Golang 泛型

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-09-23发表,共计1527字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)