你也知道, Go 将在1.18 中正式支持泛型 。依照Go每年发布两个版本的节奏,Go 1.18会在2022年春,也就是二月份左右发布,但是有可能你会在Go 1.17中尝鲜。
Go的泛型近一年来一直由Ian Lance Taylor(编译器大牛、Go核心成员)和Robert Griesemer(Go创始三巨头之一,Google V8、Chubby和HotSpot JVM的主要贡献者)等人开发,一直在dev.typeparams[^1]分支上做预研和开发工作。
由于泛型会对Go核心代码做大的修改,影响很多文件,所以我一直好奇将来dev.typeparams merge回master分支,以及他们怎么把如何管理冲突的?我们知道,Go master分支是当前的开发分支,2月份Go 1.16发布之后(也就是前几天),master分支主要是Go 1.17分支的开发,核心开发人员也会对运行时、编辑器等核心代码做改动。如果两个分支都做了一些改动,将来merge一起就会有很多的冲突,这将是一件麻烦事。使用 git +多分支开发的同学应该都深有感触。
Go开发者采用定期把master的commit merge到dev.typeparams分支方式,尽早解决冲突,我以前也是采用这种方式,因为尽早解决冲突的方式每次解决冲突的量比较少,还是可控的,但是由于master分支的开发者无需顾虑dev.typeparams分支的情况,导致最近冲突有些大,解决起来很困难,所以#43931[^2]提议将dev.typeparams分支merge到master分支,以后泛型的开发直接在master分支。
泛型特性可以通过feature flag的方式控制特性的启用和禁用,所以即使merge到master分支,也可以控制在Go 1.18再把特性启用。如果泛型的提案#43651[^3]被拒绝掉的话,相关的无用代码也可以被清除掉。
这也类似引入go module的方式,go module历经几个版本,通过GO111MODULE开关控制这个特性的启用。
比如引入 -G 开关, -G=0 启用类型检查, -G=1 启用 types2 w/o generics 支持, -G=2 使用 types2 w/ generics 支持。比如 -G=1 在Go 1.17中就默认启用, -G=2 在Go 1.18中启用。这也是很好的一种渐进式引入特性的方法。
而且在master分支开发泛型避免了merge冲突,极大减少了泛型开发者的心智负担,但是这个提议一开始遭到了Russ Cox的反对。
Rob Pike是Go语言之父,Go语言的初始三巨头之一,也是Go的精神领袖和掌门人,但是最近一两年突然很少听到他的消息了,偶尔在github能看到他的一点活跃度,目前掌门人的衣钵传给了Russ Cox。
Russ Cox反对的依据是泛型提案#43651[^3]还没有被正式接受,虽然大家都明白,这个泛型几乎一定会被加入到Go特性中,但是根据流程,一个未被批准的提案也是可能被拒绝掉了,所以现在merge到master分支的话,是违反流程的。
这是江湖规矩!
但是这一切都在泛型提案被接受的情况下解决了。所以刚才几小时,dev.typeparams分支已经被merge master分支了294331[^4]。
也就是,你可以在master分支中关注泛型的开发进度,而且也极有可能,在Go 1.17分支中开始尝鲜Go泛型的一些特性,尽管Russ Cox建议不开放这个特性,但是既然相关的工作已经实现,倒不如早点让大家尝试,或许能更早的发现问题,让Go 1.18泛型正式发布的时候更健壮,如果担心,可以默认不启用这些特性,但是可以通过开关打开这个特性。
总之,Go泛型离我们越来越近了,期望能尽早在1.17中尝试Go泛型的特性。