第16节 Go genericity(泛型)
❤️💕💕Go语言高级篇章,在此之前建议您先了解基础和进阶篇。Myblog:http://nsddd.top
Go语言基础篇
Go语言100篇进阶
[TOC]
先决条件
提示
随着 2022 年 3 月 15 日 go 1.18 正式发布,新版本除了对性能的提升之外,还引入了很多新功能,其中就有 go 期盼已久的功能泛型(Generics),同时还引入的多模块工作区(Workspaces)和模糊测试(Fuzzing)。
- **安装 Go 1.18 或更高版本。**有关安装说明,请参阅安装 Go.
- **用于编辑代码的工具。**您拥有的任何文本编辑器都可以正常工作。
- **命令终端。**Go 在 Linux 和 Mac 上的任何终端以及 Windows 中的 PowerShell 或 cmd 上运行良好。
上手–解决相加问题
💡简单的一个案例如下:
package main
import "fmt"
type MySlice[T int | float64 | string] []T
func (s MySlice[T]) Sum() T {
var sum T
for _, v := range s {
sum += v
}
return sum
}
func main() {
s := MySlice[int]{1, 2, 3}
fmt.Println(s.Sum())
v := MySlice[float64]{1.1, 2.2, 3.3}
fmt.Println(v.Sum())
u := MySlice[string]{"hello", "world"}
fmt.Println(u.Sum())
}
🚀 编译结果如下:
[Running] go run "d:\文档\最近的\awesome-golang\docs\code\go-super\71-main.go"
6
6.6
helloworld
📜 对上面的解释
泛型函数,该函数可以接收包含整数或浮点值的映射,从而有效地将刚刚编写的两个函数替换为单个函数。
若要支持任一类型的值,该单个函数将需要一种方法来声明它支持的类型。另一方面,调用代码需要一种方法来指定它是使用整数还是浮点映射进行调用。
类型参数必须支持泛型代码对其执行的所有操作。例如,如果函数的代码要尝试对其约束包含数值类型的类型参数执行string
操作(如索引),则代码将无法编译。
类比两个数也是可以的~
💡简单的一个案例如下:
package main
import "fmt"
type MySlice[T int | float64 | string] []T
func (s MySlice[T]) Sum() T {
var sum T
for _, v := range s {
sum += v
}
return sum
}
//泛型(genericity)函数
func Add[T int | float64 | string](a, b T) T {
return a + b
}
func main() {
s := MySlice[int]{1, 2, 3}
fmt.Println(s.Sum())
v := MySlice[float64]{1.1, 2.2, 3.3}
fmt.Println(v.Sum())
u := MySlice[string]{"hello", "world"}
fmt.Println(u.Sum())
fmt.Println(Add(1, 2))
fmt.Println(Add(1.1, 2.2))
fmt.Println(Add("hello", "world"))
}
🚀 编译结果如下:
[Running] go run "d:\文档\最近的\awesome-golang\docs\code\go-super\71-main.go"
6
6.6
helloworld
3
3.3000000000000003
helloworld
我们可以同过一个方法去适配很多个方法。
⚠️需要注意
func Add[T int | float64 | string](a, b T) T {
return a + b
}
注意我们的泛型(genericity)类型如果指定 any ,那么是不会成功的(interface{}
只能返回一个值
func Add[T any](a, b T) T {
return a + b
}
我们看一下 any 源码:
type any = interface{}
- any :表示 Go语言 所有内置的基本类型
- comparable:表示在Go语言里面所有内置的可比较类型
🔽 我们也可以自定义泛型(genericity)类型
自定义泛型(genericity)约束
如果类型太多了怎么办,我们针对Add[T int | float64 | string](a, b T) T
而言,我们使用 interface
定义:
/*
自定义泛型(genericity)类型
*/
package main
import "fmt"
type MyInt interface {
int | int64 | int32 | int16 | int8
}
func GetMaxNum[T MyInt](a, b T) T {
if a > b {
return a
}
return b
}
func main() {
fmt.Println(GetMaxNum(1, 2))
}
🚀 编译结果如下:2