## 简介
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泛型尝鲜 | 艺术码农的小栈]
有疑问加站长微信联系(非本文作者))