Go语言的前世今生
1. 三个大佬
Go 语言的创始人有三位,分别是
图灵奖获得者、C 语法联合发明人、Unix 之父肯·汤普森(Ken Thompson),
Plan 9 操作系统领导者、UTF-8 编码的最初设计者罗伯·派克(Rob Pike),
Java 的 HotSpot 虚拟机和 Chrome 浏览器的 JavaScript V8 引擎的设计者之一罗伯特·格瑞史莫(Robert Griesemer)。
牛逼啊,上面三个人物。虽然我记不住名字,总之很牛逼就对了!光看这个创始人,就知道go语言肯定不会差的!
2. 一次会议
他们可能都没有想到,他们三个人在 2007 年 9 月 20 日下午的一次普通讨论,就这么成为了计算机编程语言领域的一次著名历史事件,开启了一个新编程语言的历史。
那天下午,在谷歌山景城总部的那间办公室里,罗伯·派克启动了一个 C++ 工程的编译构建。按照以往的经验判断,这次构建大约需要一个小时。利用这段时间,罗伯·派克和罗伯特·格瑞史莫、肯·汤普森坐在一处,交换了关于设计一门新编程语言的想法。
之所以有这种想法,是因为当时的谷歌内部主要使用 C++ 语言构建各种系统,但 C++ 的巨大复杂性、编译构建速度慢以及在编写服务端程序时对并发支持的不足,让三位大佬觉得十分不便,他们就想着设计一门新的语言。在他们的初步构想中,这门新语言应该是能够给程序员带来快乐、匹配未来硬件发展趋势并适合用来开发谷歌内部大规模网络服务程序的。
趁热打铁!在第一天的简短讨论后,第二天这三位大佬又在谷歌总部的“雅温得(Yaounde)”会议室里具体讨论了这门新语言的设计。会后罗伯特·格瑞史莫发出了一封题为“prog lang discussion”的电邮,对这门新编程语言的功能特性做了初步的归纳总结:
这封电邮对这门新编程语言的功能特性做了归纳总结。主要思路是,在 C 语言的基础上,修正一些明显的缺陷,删除一些被诟病较多的特性,增加一些缺失的功能,比如,使用 import 替代 include、去掉宏、增加垃圾回收、支持接口等。这封电邮成为了这门新语言的第一版特性设计稿,三位大佬在这门语言的一些基础语法特性上达成了初步一致。
9 月 25 日,罗伯·派克在一封回复电邮中把这门新编程语言命名为“go”:
在罗伯·派克的心目中,“go”这个单词短小、容易输入并且在组合其他字母后便可以用来命名 Go 相关的工具,比如编译器(goc)、汇编器(goa)、链接器(gol)等(go 的早期版本曾如此命名 go 工具链,但后续版本撤销了这种命名方式,仅保留 go 这一统一的工具链名称 )。
这里我还想澄清一个误区,很多 Go 语言初学者经常称这门语言为 Golang,其实这是不对的:“Golang”仅应用于命名 Go 语言官方网站,而且当时没有用 go.com 纯粹是这个域名被占用了而已。
3. 从“三人行”到“众人拾柴”
经过早期讨论,Go 语言的三位作者在语言设计上达成初步一致后,便开启了 Go 语言迭代设计和实现的过程。
2008 年初,Unix 之父肯·汤普森实现了第一版 Go 编译器,用于验证之前的设计。这个编译器先将 Go 代码转换为 C 代码,再由 C 编译器编译成二进制文件。
到 2008 年年中,Go 的第一版设计就基本结束了。这时,同样在谷歌工作的伊恩·泰勒(Ian Lance Taylor)为 Go 语言实现了一个 gcc 的前端,这也是 Go 语言的第二个编译器。
伊恩·泰勒的这一成果不仅仅是一种鼓励,也证明了 Go 这一新语言的可行性 。有了语言的第二个实现,对 Go 的语言规范和标准库的建立也是很重要的。
随后,伊恩·泰勒以团队的第四位成员的身份正式加入 Go 语言开发团队,后面也成为了 Go 语言,以及其工具设计和实现的核心人物之一。
罗斯·考克斯(Russ Cox)是 Go 核心开发团队的第五位成员,也是在 2008 年加入的。进入团队后,罗斯·考克斯利用函数类型是“一等公民”,而且它也可以拥有自己的方法这个特性巧妙设计出了 http 包的HandlerFunc类型。
这样,我们通过显式转型就可以让一个普通函数成为满足http.Handler接口的类型了。不仅如此,罗斯·考克斯还在当时设计的基础上提出了一些更泛化的想法,比如io.Reader和io.Writer接口,这就奠定了 Go 语言的 I/O 结构模型。
后来,罗斯·考克斯成为 Go 核心技术团队的负责人,推动 Go 语言的持续演化。到这里,Go 语言最初的核心团队形成,Go 语言迈上了稳定演化的道路
在 Go 语言项目开源后,Go 语言也迎来了自己的“吉祥物”,是一只由罗伯·派克夫人芮妮·弗伦奇(Renee French)设计的地鼠,从此地鼠(gopher)也就成为了世界各地 Go 程序员的象征,Go 程序员也被昵称为 Gopher,在后面的课程中,我会直接使用 Gopher 指代 Go 语言开发者。
Go 语言项目的开源使得 Go 语言吸引了全世界开发者的目光,再加上 Go 三位作者在业界的影响力以及谷歌这座大树的加持,更多有才华的程序员加入到 Go 核心开发团队中,更多贡献者开始为 Go 语言项目添砖加瓦。于是,Go 在宣布开源的当年,也就是 2009 年,就成为了著名编程语言排行榜 TIOBE 的年度最佳编程语言。
4. 云时代的Go
时间已经来到了 2021 年。经过了十余年的打磨与优化,如今的 Go 语言已经逐渐成为了云计算时代基础设施的编程语言。你能想到的现代云计算基础设施软件的大部分流行和可靠的作品,都是用 Go 编写的,比如:Docker、Kubernetes、Prometheus、Ethereum(以太坊)、Istio、CockroachDB、InfluxDB、Terraform、Etcd、Consul 等等。当然,这个列表还在持续增加,可见 Go 语言的影响力已经十分强大。涉及云原生,以及区块链的,go是云原生的王者,知道吗,去看看cncf社区,几乎全是go。
Go 除了在云计算基础设施领域,拥有上面这些杀手级应用之外,Go 语言的用户数量也在近几年快速增加。Go 语言项目技术负责人罗斯·考克斯甚至还专门写过一篇文章,来估算全世界范围的 Gopher 数量。按照他的估算结果,全世界范围的 Gopher 数量从 2017 年年中的最多 100 万,增长到 2019 年 11 月的最多 196 万,大概两年半翻了一番。庞大的 Gopher 基数为 Go 未来的发展提供持续的增长潜力和更大的想象空间。
5. 三个很好的问题
这三个问题是我在专栏下面评论区看到的,问的很好。
“为 Go 语言实现了一个 gcc 的前端?” 怎么理解这个“前端”的意思。
在计算机专业编译原理课上大家可能都会学到一个编译器的完整编译过程包括:词法分析,语法分析,类型检查,中间代码生成,代码优化,目标代码生成,目标代码优化等几个阶段。从词法分析到中间代码生成,这就是编译器前端所要负责的事情。而代码优化和目标代码生成,则是编译器后端的职责。 文中提到了实现了一个gcc的前端,就是实现了一个程序,这个程序可以读取go源码并通过词法分析、语法分析、类型检查,最终生成中间代码,而这个中间代码可以被gcc后端所识别并生成最终目标代码。
这是一个语法层面的术语。举个简单例子,在Go中,如果一个变量的类型为int,但我要将其与另一个int64类型的变量进行加法运算,我们不能直接将它们相加,我们必须将它们显式的转换为同一类型后才能相加,这里的转换过程就简称为显式转型,这个例子转换为代码就是:
|
|
int64(a)就是对变量a进行显式转型。这个类似其他语言里面的强制类型转换
go 运行时,也称为go runtime。
它在哪里?其本身就是每个go程序的一部分,它会跟你的源码一起编译并连接到目标程序中。即便你只是写了一个hello world程序,这个程序中也包含了runtime的实现。
它在我的程序中具体负责什么?runtime负责实现go的垃圾收集、并发、内存堆栈管理以及Go语言的其他关键功能。
它的代码在哪里?它大部分以标准库的形式存放在每个Go发布版的源码中。