标签 Cpp 下的文章

跟上Go演进步伐,你只需要关注这几件事儿

本文永久链接 – https://tonybai.com/2024/09/30/how-to-keep-up-with-go-evolution

Go语言以其简洁、高效和强大的特性赢得了众多开发者的青睐。与许多主流编程语言有着明确的演进Roadmap或下一个版本spec不同,Go的演进过程更加独特、灵活与开放。这种看起来不那么正式和严肃的演进方式却也能让Go快速响应开发者的需求,同时保持语言的稳定性和一致性。

作为一名Go开发者,跟上Go的演进步伐,甚至是参与到这个激动人心的过程中来,不仅能让你更好地利用语言的新特性,还能帮助你更深入地理解Go的设计哲学。

但很多Go开发者只知道每年Go有两次的大版本Release,并通过大版本的Release Notes来了解Go的演进。这无可厚非,但对于那些想及时跟进Go演进的Gopher来说,光有一年两次的Release Notes还是不够的的,很难及时跟进Go的演进决策。

但如果直接到Go语言项目的issue中去翻阅,面对Go丰富的社区讨论和频繁的更新,你可能会感到无从下手。别担心,本文将为你指明方向,让你只需关注几个关键点,就能轻松跟上Go的演进步伐。

1. 开发计划早知道

Go的版本规划具有很高的灵活性。每个Go 1.x版本在开发前,Go语言项目相关人员都会在golang-dev讨论组上发布一个帖子,这个帖子通常的标题为”Planning Go 1.x”,例如”Planning Go 1.23″,如下图:

很多contributor,无论是Go团队的,还是外部贡献者的,会在该帖子下面留下自己的plan(注意:这些plan中的特性可不一定会在最终的版本中发布),然后等main tree开放后,就会将已经准备完毕的cl(changelist) merge到main tree中去,或开始提交cl,等待Go团队或社区的开发者进行评审。

当然对于Go 1.x这样的大版本,Go团队会在github建立专门的milestone跟踪,大家也可以在对应的milestone中看到该版本带来的新特性等,下图是目前正在积极开发的Go 1.24版本里程碑

通过查看这些Plan或定期查看Go 1.x里程碑,你可以提前了解Go的发展方向,为新版本的到来做好准备。

当然如果要了解那些更早的Go演进的决策,我们还得关注和跟踪下面的Proposal Project看板和三个关键的issue。

2. Proposal Project看板和三个关键的Issue

Go在早期并没有规范的proposal提案流程,更多是由Rob Pike、Robert Griesemer等三个Go语言之父,外加Ian Taylor和Russ Cox讨论确定,这一状态在Russ Cox建立明确的Go proposal提案流程后结束,提案流程是Go团队审查提案并决定接受或拒绝提案的过程。Russ Cox在提案流程中明确了Go项目的开发过程是设计驱动(design-driven)的,必须首先对语言、库或工具的重大更改进行讨论(包括Go语言项目主仓库和所有golang.org/x仓库中的API更改,以及对go command的命令行更改),并在实现这些设计之前进行正式记录。

Go团队目前使用Proposal Project看板和GitHub Issues来追踪语言的演进,下面我们来看看这个看板和值得关注的三个Issue。

2.1 Proposal Project看板

Proposal Project看板是Go团队跟踪proposal的全局视图,当然要理解该看板,我们需要先来简单看看Go的proposal流程以及每个提案的生命周期是怎样的。

Go Proposal流程并不复杂,可以概括为下面这个示意图:

该流程图展示了Go提案流程的几个主要步骤:

  • 任何人都可以作为提案作者,在Go项目上创建一个简短的issue来描述提案。
  • Go团队成员以及任何Go社区成员在issue上进行初步讨论,由一组人组成的Go提案审核委员会决定是接受提案、拒绝提案,还是需要进一步的设计文档。
  • 如果需要进一步的设计文档,提案作者会撰写一个详细的设计文档。
  • 在设计文档的评论减少/收敛后(意见趋于一致后),由Go提案审核委员会会进行最终讨论,决定接受或拒绝提案。

Go提案审查委员会使用GitHub项目看板来跟踪提案的状态并管理提案的生命周期(如下图所示):

该看板针对每个提案issue设置了几个生命周期状态:

  • Incoming:新提交的提案
  • Active:正在积极讨论的提案
  • Likely Accept / Likely Decline:可能被接受或拒绝的提案
  • Accepted / Declined:已被接受或拒绝的提案
  • Hold:需要设计修订或需要几周或更长时间才能获得附加信息的提案,这类提案一旦准备就绪,还会回到Active状态

了解了上述Go提案与审核流程,再看下面的几个关键Issue就容易多了。

2.2 proposal: review meeting minutes(33502)

该issue于2019年8月创建,其创建者为前Go团队技术负责人Russ Cox。这是目前Go语言项目最核心的追踪Issue,它记录了Go提案审查会议的纪要,通常每周更新一次(如下图所示):

我们看到内容包括:

  • 发布当周已经决策为Accepted和Declined的proposal列表
  • 后续Likely Accept和Likely Decline的proposal列表
  • 正处于Active讨论的proposal列表
  • 当前处于Hold状态的proposal列表

和Go提案看板不同,该issue是对提案Issue的状态变更的记录,Gopher可以第一时间看到每周Go提案的状态更新。

由于Russ Cox已经辞去了Go团队技术负责人的头衔,从2024年9月下旬开始,Go团队新的技术负责人Austin Clements将继续主持提案审核会议,并更新该Issue。

除了Review meeting minutes这个重要的issue外,还有两个issue值得我们关注,通过它们,我们可以及时了解到Go编译器和运行时的演进以及Go语法特性的演进。

2.3 Go compiler and runtime meeting notes(43930)

Go编译器和运行时团队定期(大约每周)召开会议,讨论Go编译器和运行时的后续开发和演进事宜,该会议是Google Go团队的内部会议,但Go团队觉得Go社区有必要了解这个会议上的一些讨论议题、过程与会议结论,从而知道Go编译器和运行时团队正在以及将要做什么。

于是前Go团队成员Jeremy Faller于2021年1月创建了该Issue,向Go社区发布Go编译器和运行时的最新演进动向。

之前Go编译器和运行时团队的负责人是Austin Clements,如今是CherryMui

2.4 spec: language change review meeting minutes(33892)

编译器和运行时之外,Gopher最关心的就是Go语法的演进以及Go语言规范的变更,这个事儿是由Go语言之父之一的Robert Griesemer亲自抓的。在2019年8月,Robert Griesemer就建立了跟踪Go语法变化的issue,当然最初是要跟踪Go2的演进,后来Go泛型落地后,Go2彻底融入了Go1,该issue也就变成了跟踪Go语法演进的Issue。Robert Griesemer主持的Go语言变更审查会议每月举行一次,并将会议讨论的记录发布到该Issue上。

3. Discussion与Russ Cox博客

关于Go语言演进的动向,还有两个渠道可以关注,一个是Go团队在github repo上发起的discussionRuss Cox在2021年7月启用了discussion,旨在寻找一个地方来扩大许多人可能想要参与的讨论。当前,该discussion仅针对非常有限的事项添加讨论,并且只有少数Go核心团队的人才有发起discussion的权限。一些在前几个版本的重要语言特性变化以及标准库的变化,都在这里进行了充分的讨论,比如loopvar语义修正自定义iterator开启标准库major版本更新的math/rand/v2以及gonew工具等。

另外一个则是Russ Cox的博客,作为Go项目团队前技术负责人,作为Rob Pike的接班人,Russ Cox很好地完成了承上启下的作用,并为Go的演进和发展确立了演进框架、方法以及方向。Russ Cox经常在自己的博客上先“憋大招,做铺垫”!最典型的就是vgo,也就是go module的前身,在短短几周内Russ Cox在博客上发表了7篇关于vgo的设计思路文章,为后来Go module的落地奠定了基础,至此基本上不再有Gopher抱怨Go依赖管理了。Russ Cox现已辞去Go技术负责人的头衔,后续是否还能在他的博客上看到Go相关的新特性的设计,让我们拭目以待!

4. 小结

在快速发展的技术环境中,Go语言以其独特的演进方式和灵活的开发计划,吸引了越来越多的开发者。本文介绍了如何及时有效地跟踪Go的演进的方法,包括关注大版本开发计划、Proposal Project看板和关键的issue,帮助Gopher及时了解语言的新特性与设计决策。通过参与讨论和关注Go团队的动态,开发者不仅能掌握最新的语言更新,还能深入理解Go的设计哲学和发展方向。希望每位Gopher都能抓住这些资源,与Go语言共同成长,提升自己的开发技能。


Gopher部落知识星球在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily
  • Gopher Daily Feed订阅 – https://gopherdaily.tonybai.com/feed

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

“类型名称”在Go语言规范中的演变

本文永久链接 – https://tonybai.com/2024/09/24/the-evolution-of-type-name-in-go-spec

Go语言规范(The Go Programming Language Specification)是Go语言的核心文档,定义了该语言的语法、类型系统和运行时行为。Go语言规范的存在使得开发者在实现Go编译器时可以依赖一致的标准,它确保了语言的稳定性和一致性,特别是在类型系统设计中,Go团队通过规范推动了语言的简洁性、稳定性与可维护性。对于Go开发者而言,Go语言规范也是语法特性使用的参考手册(虽然语言规范读起来比较抽象和晦涩)。

Go语言规范由Google的Go核心开发团队维护和演进,这与ISO标准的C/C++语言规范有所不同。C和C++语言的ISO标准更新较慢,需经过复杂的全球共识和审核流程,而相比之下,Go语言的管理方式就显得更加灵活,也能够迅速适应新需求。

然而,这种灵活性也带来了潜在的弊端。随着新语法特性的引入和演进,一些已有的概念的含义可能会发生变化,导致前后的不一致性,从而让开发者感到困惑。例如,Go中的Type Name(类型名称)就经历了从最初的Named Type,到Defined Type和Alias Type,最终又回归到Named Type的过程。

近期Go语言之父之一的Robert Griesemer在Go官博发表了一篇名为”What’s in an (Alias) Name?“的文章,其中就对Go spec中Type Name的历史演进做了回顾,这里我们就基于这段回顾对“类型名称(Type Name)”在Go语言规范中的演变做一下简要梳理,希望能帮助大家更好的理解Go。

1. Go规范中的Type Name(类型名称)

在Go语言规范中,Type Name是指给定类型的标识符,它为一个类型提供了唯一的名称。Type Name用于识别和引用各种类型,这包括Go内置(也叫预声明Predeclared Type)的基础类型(比如int、string)和用户自定义的类型,比如:

var x int       // int是基础类型的Type Name
type MyInt int  // MyInt是用户定义类型的Type Name

你可能会问,Go还有没有类型名称的类型吗?当然有了,有一些特殊的类型没有直接的类型名称。通常,这些类型是匿名类型(Anonymous Type),即它们并没有通过命名来标识,主要的匿名类型包括:

  • 字面量定义的复合类型(Composite Literals)

Go支持在代码中使用复合字面量来定义结构体、数组、切片、map等类型,而不为这些类型显式地定义名称。这些类型是在使用时定义的,并没有为其单独声明一个类型名称。

var data = struct { Name string; Age int }{"Alice", 30}  // 匿名结构体类型
var arr = [5]int{1,2,3,4,5} // 匿名数组类型
var arr = []int{1, 2, 3}  // 匿名切片类型
var m = map[string]int{"foo": 1, "bar": 2}  // 匿名map类型
  • 匿名函数类型

Go支持函数作为一等公民,函数本身可以作为类型,当定义匿名函数(即未命名函数)时,这些函数没有类型名称。

var f = func() int { //匿名函数类型func() int
    return 42
}

Type Name是一个广泛的概念,在Go spec中,Go设计者们将其做了细分,比如Named Type、Defined Type等。那么随着Go版本的变化,Go中的Type Name的分类有哪些重要的演进和变化呢,下面我们就重点说明一下Go spec中Type Name分类的三次重要变化。

2. 初始阶段:简单而明确的Named Type (2009-2017)

Go 1.0是Go语言的首个正式发布版本,其中确立了类型名称的基础概念。在这一阶段,Go的类型系统已经具备了高度的简洁性和一致性,这也是该语言设计的核心原则之一。

在Go语言的早期阶段(2009-2017),Go规范就确定了简单明确的Named Type的概念,它指的是通过下面语法定义的类型T:

type T existingType

这些通过类型声明定义的T被称为Named Type。而这里的existingType可以Predeclared的预声明类型(比如int、string),可以是已存在的Named Type,也可以是前面提到的匿名类型。

通过给现有类型赋予新名称来定义新的类型,与匿名类型等未命名类型形成鲜明对比。这种简单的分类满足了早期Go程序员的需求,为代码组织和类型系统提供了清晰的基础,提升了代码的可读性和模块化。

我们可以用示意图来展示这个阶段的Go类型名称分类:

而Named Type的定义方式也可以用下图表示:

我们看到,可以基于Predeclare Type、匿名类型以及已存在的Named Type来定义一个新的Named Type。并且,Named Type具有一些专有特性,比如可拥有自己的方法、只与自身类型赋值兼容,不与其底层类型直接兼容(除非进行显式类型转换)等。

3. 变革之始:别名类型的引入 (Go 1.9, 2017)

然而,随着Go 1.9在2017年引入别名类型(Alias Type),情况开始变得复杂:

type T = Q // T为Q类型的别名类型

别名类型的引入是为了支持大规模代码库的重构,但它也模糊了Named Type的界限,因为别名也是一个类型名称。

为了应对这一变化,Go团队引入了”Defined Type”的概念以代替界限模糊的Named Type,用以特指通过类型定义(type T Q)创建的新类型。

这样改动后,整个Go类型系统的类型名称分类就变成如下示意图中的状态了:

Defined Type定义和Alias Type的定义分别如下:

两者看起来差别不大,但只有Defined Type才拥有专有属性,比如可拥有自己的方法、只与自身类型赋值兼容等。我们也可以为Alias Type定义方法,但那个方法属于原类型。

4. 泛型时代的到来:概念的重塑 (Go 1.18, 2022)

2022年,Go 1.18的发布标志着Go语言进入了泛型时代,这一重大特性的引入再次挑战了现有的类型分类方式。

比如类型参数也是类型,它们有名称,与Defined Type一样,两个不同命名的类型参数表示不同的类型。换句话说,类型参数是Named Type,而且它们的行为在某些方面与Go原始的Named Type类似。更重要的是,Go的Predeclare Type(如int、string等)只能通过它们的名称来访问,并且像Defined Type和类型参数一样,如果它们的名称不同,它们也会不同,这样预声明的类型也变成了Named Type。

为了适应泛型,Go规范重新引入了Named Type,并将其范围扩大到包括预声明类型、Defined Type、类型参数以及部分情况下的别名类型。

重新引入Named Type后,Defined Type依然得以保留,整个Go系统类型的最新类型名称分类状态如下图所示:

5. 当前的权衡

在”What’s in an (Alias) Name?“的文章中,Robert还提到了学院派类型系统理论中的Nominal type(名义类型)和Structural type(结构类型)两个概念,虽然Go spec目前完全没有使用这两个概念。

Nominal type,也叫名义类型。这种类型的身份(identity)明确地与其名称相关联。两个类型即使结构完全相同,如果名称不同,也被视为不同的类型。像Go 1.18以后spec中的预声明类型(如int、string等)、Defined types(通过type关键字定义的类型)和类型参数都属于这种类型,这大体与Named Type是重叠的。

Structural type(结构类型)的类型的身份仅取决于其结构或组成,而不依赖于名称。如果两个类型的结构相同,它们就被视为相同的类型,即使它们可能有不同的名称,像Go中的接口类型(在某种意义上)、通过类型字面量创建的类型(如匿名结构体、函数类型等)等都可以归属与这种类型。值得注意的是,指向类型字面量的别名类型(如type AliasName = struct{ … })也可看作是structural type。

不过Robert也提到了,后续Go还会继续沿用Named Type、Defined Type等术语,而不会用这些学院派的类型术语来更新Go spec,这主要有几方面考虑:

  • 历史一致性:Go语言从早期就使用了named type、defined type等术语。突然改变可能会导致现有文档、教程和代码库的混乱。
  • 概念特殊性:Go的类型系统有其特殊性,不完全符合传统的nominal/structural二分法。例如,Go的接口类型结合了nominal和structural的特性。这么做,也可以避免引起其他语言中该术语用法的混淆。
  • 实用性考虑:”named type”、”defined type”等术语在Go的上下文中有明确的含义,直接对应于语言的特定特性和语法结构。这使得它们在讨论Go特定概念时更加实用。

6. 小结

本文基于Robert的文章讲述了Go语言类型系统中的类型名称的演变历程。我们回顾了Type Name在Go语言规范中的重要变化,从最初的简单Named Type到后来的Defined Type和Alias Type,再到引入泛型时代后的重新定义Named Type。每一次变化不仅反映了Go语言的不断发展,也展示了Go团队在应对复杂性和保持语言简洁性之间的平衡。


Gopher部落知识星球在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite
  • Gopher Daily归档 – https://github.com/bigwhite/gopherdaily
  • Gopher Daily Feed订阅 – https://gopherdaily.tonybai.com/feed

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats