Tony Bai · Go 语言第一课
Tony Bai
资深架构师,tonybai.com 博主
21492 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 59 讲
开篇词 (1讲)
结束语 (1讲)
Tony Bai · Go 语言第一课
15
15
1.0x
00:00/00:00
登录|注册

40|驯服泛型:定义泛型约束

你好,我是 Tony Bai。
在上一讲中我们对 Go 泛型的实现方案“类型参数语法”做了较为全面的学习,我们掌握了泛型函数、泛型类型和泛型方法的定义和使用方法。不过还有一处语法点我们并没有重点说明,它就是用于声明类型参数的约束(constraint)。
虽然泛型是开发人员表达“通用代码”的一种重要方式,但这并不意味着所有泛型代码对所有类型都适用。更多的时候,我们需要对泛型函数的类型参数以及泛型函数中的实现代码设置限制。泛型函数调用者只能传递满足限制条件的类型实参,泛型函数内部也只能以类型参数允许的方式使用这些类型实参值。在 Go 泛型语法中,我们使用类型参数约束(type parameter constraint)(以下简称约束)来表达这种限制条件。
就像上一讲提到的,约束之于类型参数就好比函数参数列表中的类型之于参数:
函数普通参数在函数实现代码中可以表现出来的性质与可以参与的运算由参数类型限制,而泛型函数的类型参数就由约束(constraint)来限制。
2018 年 8 月由伊恩·泰勒和罗伯特·格瑞史莫主写的 Go 泛型第一版设计方案中,Go 引入了 contract 关键字来定义泛型类型参数的约束。但经过约两年的 Go 社区公示和讨论,在 2020 年 6 月末发布的泛型新设计方案中,Go 团队又放弃了新引入的 contract 关键字,转而采用已有的 interface 类型来替代 contract 定义约束。这一改变得到了 Go 社区的大力支持。使用 interface 类型作为约束的定义方法能够最大程度地复用已有语法,并抑制语言引入泛型后的复杂度。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Go泛型中的类型参数约束是关键的限制条件,用于确保泛型代码对特定类型的适用性。本文深入介绍了内置约束如any和comparable,以及自定义约束的实现方法。同时,还探讨了接口类型语法的扩展,支持在接口类型中放入类型元素信息,以及新概念:类型集合。这些内容帮助读者更深入地理解Go泛型中类型参数约束的使用方法和限制条件。此外,文章还介绍了简化版的约束形式和约束的类型推断,为读者提供更多的使用技巧和实践经验。通过实例分析和代码验证,读者可以更好地理解泛型参数的约束形式和类型推断的应用场景。总的来说,本文通过深入讲解Go泛型中类型参数约束的相关概念和技术特点,为读者提供了全面的指导和实践经验,帮助他们更好地应用泛型特性进行编程。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Tony Bai · Go 语言第一课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(7)

  • 最新
  • 精选
  • Geek14
    type Intf1 interface { int | string F1() F2() } Intf1的类型集合是个空集合。因为int和string都没有实现F1和F2方法。 任何集合与空集合求交集结果还是空集合。所有I的类型集合也是空集合。

    作者回复: 👍

    2023-01-05归属地:北京
    3
  • 撕影
    int | ~string | Intf2 的类型集合:{以 int 为底层类型的所有类型,以 float64 为底层类型的所有类型} 这一句应该加上 “以string 为底层类型的所有类型” 这里不加上但会对读者理解造成障碍 不加上也不影响最终编译结果 ~string是被外层求交集操作剔除的(只剩string本身,但是string本身作为基本类型又不能作为方法的receiver:)

    作者回复: 看的很细致👍。后续这个建议我让编辑老师更新一下,加上“以string 为底层类型的所有类型”。

    2023-01-18归属地:湖南
    2
  • lesserror
    Tony bai 老师,有几个几个问题: 1. 文中说:“它的类型集合为 int、~string 和 Intf2 方法集合的并集”,这里 Intf2 方法,这里的方法该怎么理解,这里的 Intf2 不是一个只含有类型元素的接口吗? 2. 文中:“ int | ~string | Intf2 的类型集合:{以 int 为底层类型的所有类型,以 float64 为底层类型的所有类型,以 string 为底层类型的所有类型}。” 这里没有包含 int,是因为 Intf2 中的 ~int 包含这里的 int 类型,所以并集中并没有出现 int,是这样的吗?

    作者回复: 1. typo,应为类型集合的并集。稍后让编辑老师改一下,感谢发现。 2. 对的。因为 Intf2 中的 ~int 包含这里的 int 类型,所以并集中并没有出现 int

    2023-08-05归属地:广东
    1
  • Sunrise
    还是搞不懂为啥 go 泛型用中括号表示而不用<>,如果单纯为了避免和小于号大于号冲突那么下面不也冲突了吗 type MyStruct [T * int]struct{} // 编译错误:undefined: T // 编译错误:int (type) is not an expression 这块如果用<>表示不就可以避免了吗

    作者回复: 我理解: 使用<>对于一些情况是无解的。而使用[ ]尽管有些时候也会模棱两可,但至少还有解,比如上面的情况。

    2022-11-28归属地:美国
    1
  • 罗杰
    新项目已经使用1.19了,看来至少不要再用 interface{},还是 any 直观。

    作者回复: 少敲了8个字母呢:)。

    2022-11-08归属地:北京
    3
  • 撕影
    int | ~string | Intf2 的类型集合:{以 int 为底层类型的所有类型,以 float64 为底层类型的所有类型} 是不是还应该加上 “以 string 为底层类型的所有类型” ?
    2023-01-18归属地:湖南
  • Tokamak
    不支持 type MyInt int 这种基于int为底层数据的类型
    2022-11-14归属地:重庆
收起评论
显示
设置
留言
7
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部