Go 1.17泛型尝鲜

简介

Go不支持泛型,但是对泛型呼声一直存在,所以Go也一直在努力支持,这次发布的1.17实际上就已经包含了泛型的功能,但是默认是不开启,需要增加:-G=3参数来开启:go run -gcflags=-G=3 main.go

Go的泛型有以下应用场景

例子

泛化形参数组

定义一个函数helloSlice,接收切片参数s,元素类型为任意类型T

代码:

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 run -gcflags=-G=3 main.go

输出

123
helloworld

泛化参数格式

约束参数格式,只允许参数类型是指定格式,例如:约束plus的参数类型必须为 int, string

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 run -gcflags=-G=3 main.go

输出

3
helloworld

如果类型非法时会报错

fmt.Println(plus(int64(1), int64(2))) // 不支持int64

报错:

# command-line-arguments
./main.go:15:18: int64 does not satisfy PlusAble (int64 not found in int, string)

定义泛化切片

定义一个切片,切片的元素格式为任意类型,代码

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()

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 run -gcflags=-G=3 main.go

结果

hello
world

双重约束

同时切片中的参数必须是指定类型,且实现方法指定方法

代码

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 run -gcflags=-G=3 main.go

结果

hello
world

如果元素类型是string没有实现Print方法

func main() {
   var ss [] string
   ss= append(ss, "Hello")
   ss= append(ss, "World")
   doPrints(ss)
}

异常

# command-line-arguments
./main.go:28:10: string does not satisfy Printer (missing method Print)

我的博客:Go 1.17泛型尝鲜 | 艺术码农的小栈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值