7

历时 11 年,Go 编译器终于正式支持泛型!

 4 years ago
source link: https://segmentfault.com/a/1190000040559074
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

历时 11 年,Go 编译器终于正式支持泛型!

近日,据外媒报道,Go 项目代码仓库在最新提交和合并的一个 PR 中,Go 语言已在 cmd/compile 中默认启用 -G=3。据描述,该 PR 已将 cmd/compile 的 -G flag 的默认值从 0 改为 3,可使用新 types2 类型检查器并支持类型参数,正式启用对泛型的支持。

出于对默认行为变化的考虑(例如,types2 类型检查器已知的变更),此次 Go编译器默认启用 -G=3,正式启用泛型变更的同时,也更新了回归测试工具。另外,尽管已默认启用 -G=3,但目前 -G=0 模式目前仍在测试中。

自 2009 年诞生之后,谷歌开发的编程语言 Go 发展至今已有 11 年了。凭借诸多优势(如比Python更快,比Java更简洁,有着C++没有的GC),Go 编译器一直都深受科技公司开发者或编程人员们的青睐。当然近几年,Go 也越来越多地出现在金融和媒体等行业。

作为一项成功的开源项目,使用 Go 编译器的人群数量每年都在增长。过去的几年里,面对广泛的 Go 开发者们的的调查显示,泛型一直被认为是 Go 确实的关键。甚至一度从 2010 年讨论至今,其中不乏一些关于 Go 泛型草案的反馈和建议。

为什么 Go 语言一直没有泛型

在此之前,很多人都认为 Go 语言或许永远都不会加入泛型了。那么,为什么 Go 语言到目前为止都一直没有泛型?如今,Go 编译器默认启用 -G=3,正式启用泛型,那么“困扰多年”的问题又是如何被解决的呢?

相信对于 Go 语言标准库了解的朋友,会在如下的代码中发现有趣的问题:

package sort

func Float64s(a []float64)
func Strings(a []string)
func Ints(a []int)
...

在上述这个以 sort 包提供的函数里,尽管它们拥有非常相似的底层逻辑和功能,但在传入类型不同时却需要对外提供多个函数。这个时候,如果能像 Java 那样使用泛型的话,就能大大减少重复的代码和逻辑,也能为编程人员提供更强的表达能力,减少工作量的同时还能提升效率。

相关调查数据显示,由于泛型困境,此前谷歌 Go 编程语言开发团队不得不面临开发效率、编译速度和运行速度的选取。与此同时,由于之前 Go 语言方案存在缺陷, Go 团队也认为泛型的支持不够紧凑,因此一直没在 Go 语言前几个版本中加入泛型。

关于Go语言泛型的发展

一直以来,关于 Go 语言泛型的“推进”工作就一直在进行。

2009 年 11 月 ,Google 正式将Go语言以开放源代码的形式向全球发布。第二年,Ian Lance Taylor 就提交了为Go添加泛型的提议,但当时该提议只是作为示例保存了起来,并没有被采纳。此后的2012年3月,Go 1 正式发布,泛型提议再次被提起。

之后几年里,由于上述讲到的 Go 面临的“泛型困境”,相关提议也一直在被考虑和在被解决的过程中。一直到 2019 年7月,Ian Lance Taylor 在 Gophercon 2019 上发表关于 “Why Generics?” 的演讲时,才正式提交了一份合作泛型设计的草稿。

去年 6 月,这份泛型设计草稿有了更新,才终于被预测能在今年 Go 1.17 版本上见到的可能。

从今年 1 月,Ian Lance Taylor 发起了添加泛型的提案,到 3 月关于泛型提案正式发布,再到刚刚Go编译器正式启用 -G=3 支持泛型,历时多年,广大 Go 开发者群体关注的 Go 语言的泛型问题终于得以实现。

最后,避免泛型滥用

时至今日,在语言代码编译器的使用过程中,泛型都是极具“进化”性质的一项功能,不仅可以提高开发效率,还能有效帮助开发者减少不必要的重复工作。

但如同任何一门编辑语言一样,Go 语言的泛型启用,此后发展过程中的“泛型滥用”也需要值得关注。

相信对于每个编程人员来说,在代码中发现大量被嵌套使用的泛型的时候,都会"如临大敌”。虽然不似 C++ 那样标准库中大量的模板,但 Go 语言的泛型特征中,也容许使用类型约束,类似 Java 那样产生“迷”一样的逻辑,会给代码编译效率带来不少影响。

因此,在引入泛型特征后,Go 语言又将如何处理“函数重命名”逻辑,来帮助有效解决源码中类型、函数和方法呢?我们将拭目以待。

关于 Go 的更多详情,可关注:
https://go-review.googlesourc...


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK