泛型 Go VS TypeScript

我们知道,Go 最开始是不支持泛型的,最近版本(1.18)才开始支持。在支持泛型之前,一些夸类型的操作不得不通过反射来实现。那如何在 Go 中来使用泛型呢,我们可以跟我们熟悉的 TS 来做一个比较。

泛型的基础概念

  • 基本的泛型函数, 如果没有泛型,我们就需要分别定义多个函数,或者用 any 作为类型。通过泛型,我们可以对不同类型的参数做类似的处理。比如:

    go 复制代码
    func minValue[T float32 | float64 | int16 | int32 | int64 | int](a T, b T) T {
            if a < b {
                    return a
            }
    
            return b
    }
    
    minValue[int](1, 2)
  • 泛型的类型推断, 这里,我们在函数调用的时候制定了类型约束,实际上我们已经可以通过函数参数的上下文得知,我们的类型约束为 int, 这里可以简写成:

    go 复制代码
    minValue(1, 2)
  • 定义类型约束, 在泛型的类型约束中,我们会写的比较长,是否可以进行约束的定义呢。我们可以使用 interface 关键字来进行类型约束定义:

    go 复制代码
    type Number interface {
        float32 | float64 | int16 | int32 | int64 | int
    }
    
    func minValue[T Number](a T, b T) T {
        if a < b {
            return a
        }
    
        return b
    }
  • ~ 关键字的使用, 有时候,我们会使用自定义类型, 比如:

    go 复制代码
    type MyFloat float32
    
    var a1 MyFloat = 0.1
    var a2 MyFloat = 0.2
    
    minValue(a1, a2)

    这里会出现类型错误:MyFloat does not satisfy Number (possibly missing ~ for float32 in Number) 其实很容易,如果需要支持自定义的类型,只需要在类型约束前加上:~,比如:

    go 复制代码
    type Number interface {
        ~float32 | ~float64 | ~int16 | ~int32 | ~int64 | ~int
    }

泛型的进阶

  • 类型约束和接口,我们知道 interface 既可以用来做类型约束,也可以用来做接口定义。某种程度上说,他们是一致的,比如:

    • 我们通过约束 C1 定义泛型函数:

      go 复制代码
      type C1 interface {
          ~int | ~int32
          M1()
      }
      
      func foo[P C1](t P) {
      }
    • 同时我们定义 T 实现接口,但是不实现类型约束:

      go 复制代码
      type T struct{}
      func (T) M1() {}
      
      var t T
      foo(t) // 编译器报错:T does not satisfy C1 (T missing in ~int | ~int32)
    • 如果我们实现了类型约束但是没有实现接口:

      go 复制代码
      type T int
      var t T
      foo(t) // T does not satisfy C1 (missing method M1)
    • 只有同时满足了类型约束和接口实现才能通过编译:

      go 复制代码
      type T int
      func (T) M1() {}
      
      var t T
      foo(t) // 编译器报错:T does not satisfy C1 (T missing in ~int | ~int32)
相关推荐
雪隐40 分钟前
个人电脑玩AI00-前言
人工智能·后端
我是一颗柠檬1 小时前
【Java后端技术亮点】动态路由权限(按钮级权限),细粒度控制到按钮级别
java·开发语言·后端·状态模式
前端Hardy1 小时前
CSS 动画真的比 JS 快?Josh Comeau 做了组实验,结果跟直觉不一样
前端·javascript·后端
Front思1 小时前
调取支付宝支付正式环境不可以唤起来,但是沙箱可以
后端
foggyprojects1 小时前
AI 生成 SQL 模板以后,为什么还需要固定 helper 规则
后端
明天一点1 小时前
Cloudflare 通知转发钉钉机器人
前端·后端
前端Hardy1 小时前
前端日历组件,要变天了?Schedule-X v4.6 彻底杀疯了
前端·javascript·后端
Oo_行者_oO1 小时前
微服务 Feign 从“万能公共服务”到“业务客户端”
后端·架构
wei_shuo1 小时前
别再踩坑了!KingbaseES 存储过程与触发器开发避坑实录
后端
元宝骑士1 小时前
MySQL 实战:跨表排序 + 指定类型置顶四种写法
后端·mysql