Go 泛型

泛型又叫类型参数化,指在函数、方法、接口以及类定义的时不局限指定某一种特定类型,而是其调用者来决定具体使用哪种类型的参数;

没有泛型,当针对不同类型的相同逻辑处理会增加大量重复代码:

func AddInt(res ...int) (ans int) {   for _, v := range res {      ans += v   }   return}func AddFloat64(res ...float64) (ans float64) {   for _, v := range res {      ans += v   }   return}

泛型版本发布前, 用空接口interface{} 实现泛型函数:

func Add(res ...interface{}) (ans interface{}) {   ans = res[0]   for i := 1; i < len(res); i++ {      switch x := res[i].(type) {      case int:         ans = ans.(int) + x      case string:         ans = ans.(string) + x      case float64:         ans = ans.(float64) + x      }   }   return}

1.18版本泛型发布:

1.新增关键字:any、comparable,很明显any就是空接口;

// any is an alias for interface{} and is equivalent to interface{} in all ways.type any = interface{}// comparable is an interface that is implemented by all comparable types// (booleans, numbers, strings, pointers, channels, arrays of comparable types,// structs whose fields are all comparable types).// The comparable interface may only be used as a type parameter constraint,// not as the type of a variable.type comparable interface{ comparable }

2.新增泛型约束的概念;

//===两种表现形式===//定义约束接口type Integer interface {   int | int8 | int16 | int32 | int64}func PrintInteger[T Integer](a T) {   fmt.Println(a)}//直接行内多个类型组合func PrintInteger[T int | int8 | int16 | int32 | int64](a T) {   fmt.Println(a)}//===================type MyInt interface {   ~int //~表示该约束对任何以int为底层类型的类型有效}

所以之前多值累加函数可改为:

func Add[T ~int | ~float64 | ~string](res ...T) (ans T) {   for _, v := range res {      ans += v   }   return}

但go中泛型使用存在一些限制:

限制一:泛型约束必须是一个接口,不能是结构体;

解决方案:通过实现指定接口,将接口约束转移到结构体上;

type Entity interface {   Id() int64   SetId(id int64)}type BaseEntity struct {   id int64}func (b *BaseEntity) Id() int64 {   return b.id}func (b *BaseEntity) SetId(id int64) {   b.id = id}type EntityA struct {   BaseEntity}type EntityB struct {   BaseEntity}func Selector[E Entity](a E) {   fmt.Println(a)}func main() {    Selector(new(EntityA))    Selector(new(EntityB))}

限制二:接口和结构体无法使用泛型方法;

解决方案:结构体泛型化

type Entity[T any] struct {}func (e *Entity[T]) Exec(res ...T) {}func main() {   a := &Entity[int]{}   a.Exec(1, 2)   b := &Entity[string]{}   b.Exec("a", "b")}

限制三:泛型约束不能用于参数,只能和泛型结合一起使用;

解决方案:标记接口

type MyEntity interface {   mark()}type EntityA struct {}type EntityB struct {}func (e EntityA) mark() {}func (e EntityB) mark() {}type Conn struct {}func (c *Conn) Exec(res ...MyEntity) {}
Go   泛型
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章