Go 1.17泛型尝鲜

uuid · · 1247 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

## 简介 Go不支持泛型,但是对泛型呼声一直存在,所以Go也一直在努力支持,这次发布的1.17实际上就已经包含了泛型的功能,但是默认是不开启,需要增加:**-G=3**参数来开启:**go run -gcflags=-G=3 main.go** Go的泛型有以下应用场景 ## 例子 ### 泛化形参数组 定义一个函数helloSlice,接收切片参数s,元素类型为**任意类型T** 代码: ```go package main import "fmt" // T 自定义类型 func helloSlice[T any] (s []T) { for _, v := range s { fmt.Printf("%v", v) } fmt.Print("\n") } func main() { // 调用1:指定T类型为int helloSlice[int]([]int{1, 2, 3}) // 调用2:不指定类型 helloSlice([]string{"hello", "world"}) } ``` 运行 ```go go run -gcflags=-G=3 main.go ``` 输出 ``` 123 helloworld ``` ### 泛化参数格式 约束参数格式,只允许参数类型是指定格式,例如:约束plus的参数**类型必须为** int, string ```go package main import "fmt" type PlusAble interface { type int, string // 限制只能int 和 string类型可以相加 } // 定义T类型为PlusAble,参数a、b类型为T,返回相加结果 func plus[T PlusAble](a, b T) T { return a + b } func main() { fmt.Println(plus(1, 2)) fmt.Println(plus("hello", "world")) } ``` 运行 ```go go run -gcflags=-G=3 main.go ``` 输出 ```go 3 helloworld ``` 如果类型非法时会报错 ```go fmt.Println(plus(int64(1), int64(2))) // 不支持int64 ``` **报错:** ```go # command-line-arguments ./main.go:15:18: int64 does not satisfy PlusAble (int64 not found in int, string) ``` ### 定义泛化切片 定义一个切片,切片的元素格式为**任意类型**,代码 ```go package main import "fmt" // 泛型切片 type set [T any] []T func main() { vv:=set[int] {1, 3} fmt.Println(vv) } ``` 运行 ``` go run -gcflags=-G=3 main.go ``` 输出 ``` [1 3] ``` ### 元素参数必须实现指定接口 约束切片参数**必须实现指定接口**的方法:Print() ```go package main import "fmt" // 定义接口 type Printer interface { Print() } // 定义一个类型为T的泛型,切片元素的类型为T func doPrints[T Printer] (pp [] T) { for _, p := range pp { p.Print() } } // 自定义类型实现Printer接口 type myPrint struct { Value string } func (p myPrint) Print() { fmt.Println(p.Value) } func main() { var ss [] myPrint ss= append(ss, myPrint{"Hello"}) ss= append(ss, myPrint{"World"}) doPrints(ss) // 保存 } ``` 执行 ```go go run -gcflags=-G=3 main.go ``` 结果 ```go hello world ``` ### 双重约束 同时切片中的参数**必须是指定类型**,且**实现方法指定方法** 代码 ```go package main import "fmt" // 约束元素类型为指定类型、必须实现Print()方法 type Printer interface { type string Print() } // 定义一个类型为T的泛型,切片元素的类型为T func doPrints[T Printer] (pp [] T) { for _, p := range pp { p.Print() } } // 自定义类型实现Printer接口 type myPrint string func (p myPrint) Print() { fmt.Println(p) } func main() { var ss [] myPrint ss= append(ss, myPrint("Hello")) ss= append(ss, myPrint("World")) doPrints(ss) } ``` 执行 ```go go run -gcflags=-G=3 main.go ``` 结果 ```go hello world ``` 如果元素类型是string没有实现Print方法 ```go func main() { var ss [] string ss= append(ss, "Hello") ss= append(ss, "World") doPrints(ss) } ``` 异常 ```go # command-line-arguments ./main.go:28:10: string does not satisfy Printer (missing method Print) ``` 我的博客:[Go 1.17泛型尝鲜 | 艺术码农的小栈]

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1247 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传