终于!Go 1.18 将支持泛型,来听听 Go 核心技术团队怎么说

发布于 2021-11-04 14:04 ,所属分类:软件编程学习资料

技术编辑:MissD丨发自 思否编辑部
gongzhong号:SegmentFault



近日,Go 语言核心开发团队技术主管 Russ Cox 在 golang-dev group 发了公开邮件,宣布称“如果没有意外情况,Go 1.18 将会支持泛型”。


据悉,Go 1.18 版即将于2022年初发布。



还记得10月初,本站刚刚报道了“Go语言之父”Rob Pike在github上关于“不建议在Go 1.18的标准库中使用泛型”issue的消息。当时,Rob Pike的担心是“Go 1.18版本承载了太多的change,容易出错”,所以建议先等待观察,稳步向前。


而到了10月28日的昨天,Russ Cox又发文针对 Rob Pike 的 issue,介绍了Go 1.18 版本与泛型目前的进展和后续的支持策略,这也终于确定了Go核心团队下阶段的方向——也就是说,如果不出意外的话,Go 1.18版本中将支持泛型。


加入泛型对于Go团队的意义


作为Go发布以来最重要的变化,Russ Cox在这封公开邮件中简单解释了泛型的加入对Go团队和用户的意义。



Russ Cox表示,任何Go的新功能特性,无论是语言还是库,都带有不确定性,包括不确定如何使用、如何不使用它们,以及有哪些微小的bug已经通过了现有的测试集。泛型也不能避免这种不确定性,特别是由于泛型是个大型的新功能,所以它的不确定性也会更大。


同时,在该团队最初发布的泛型代码–特别是通过提案程序的maps和slices包–将首先放在golang.org/x/exp中,但不能保证向后兼容。Russ Cox称,未来一旦有了更多的经验,会希望将其中一些包推广到标准库中(constraints包例外,它作为编写某些泛型代码的基础,将被添加到Go 1.18标准库中)。


Russ Cox 强调,Go 1.18与其他Go 1.x版本一样具有向后兼容的承诺,


不会破坏用Go 1.18构建的代码,包括使用泛型的代码。在最坏的情况下,如果我们发现Go 1.18的语义有一些致命的问题,并需要改变它们(例如在Go 1.19中),我们将使用go.mod文件的go版本指示符来确定该module中的源文件是使用Go 1.18还是Go 1.19+的语义。(我们预计不需要这样做!)”


对于不少急于采用泛型的软件包作者,Russ Cox建议称“如果您正在更新您的软件包以使用泛型,请考虑将新的泛型API隔离到自己的文件中,并为其使用Go 1.18的构建标签(//go:build go1.18),以便Go 1.17用户可以继续构建和使用非泛型部分。”


值得注意的是,第三方工具可能不会在Go 1.18发布时完全支持泛型。目前,Go核心团队正在与不少第三方工具的作者沟通,试图确保他们得到适当的更新,但他们都有自己的时间安排表。


对于“为什么不把泛型变成可选项加入Go 1.18?”的疑问,Russ Cox解释称,减少不确定性的唯一方法是让其默认可用。


“当我们在Go 1.5版本中让vendor机制作为可选项加入时,发现几乎没有人真正使用它,直到Go 1.6版本默认开启它。所以Go 1.5版本没有减少我们对Go开发者使用vendor情况的不确定性。另一方面,Go 1.5版本无疑将生态系统分为’在标准Go下运行的代码‘和 ’在启用vendoring后运行的代码‘两部分。我们希望在这里尽可能地避免这种结果。”


Go语言为什么需要泛型?


一直以来,业界关于Go语言泛型的话题讨论都非常激烈,而Go团队也一直对否加入泛型而犹豫不决,因为他们希望找到一种好的解决方案。


我们知道,函数式编程是一种非常流行的编程范式,在很多汇编语言类型里都有构建或支持。而对于Go语言来说,尽管并非是一种函数式语言,但它确实提供了一组允许函数式编程的特性(有相当数量的开源Go库提供功能特性集)。


函数式编程的语言支持范围从只支持函数式范式(如Haskell)到多范式+一流支持(如Scala、Elixir)再到多范式+部分支持(如Javascript、Go)。在后一类语言中,函数式编程一般通过使用社区创建的库来支持,这些库复制前两种语言的标准库中的部分或全部功能。


Go语言则属于最后一类,它可以实现下图中的功能编程:



在Go语言生态系统中,已经存在许多功能性编程库,它们在流行程度、功能和工效方面各不相同。


尽管已经支持其中的一些功能,例如一级和高阶函数以及启用函数编程,但依旧缺少一个关键特性——泛型。


如果没有泛型,Go语言的功能库和应用程序将被迫走两条路径:


一、类型安全+用例特定。选择这种方法的库实现了类型安全的设计,但只能处理某些预定义类型。由于不能使用自定义类型或结构,这些库可以应用于的问题的种类是有限的。当然这两种类型都是安全的,但仅适用于预定义的类型。


二、类型不安全+用例不可知。选择这种方法的库,实现了一种类型不安全但可应用于任何用例的设计。这些库使用自定义类型和结构,但需要权衡,如果未正确实现,会使应用程序面临运行时死机风险。这两个设计选项提供了两个类似的选项,“有限实用程序或运行时恐慌风险”。因此,最简单也是最常见的选择是不要使用带有命令式风格的函数式编程库。


所以现在,随着 Go 1.18 版的到来,Go团队也正式宣布泛型终于要被添加进去了,以在Go语言中实现新的函数式编程解决方案。


自从Go 1.18“支持泛型”的消息传开之后,一些外媒随即整理了一些基于Go泛型(Go 1.18)的函数库,可以添加到切片包中,供开发者使用。但我们在这里建议大家,希望一切以官方信息为主。


-END -

相关资源