vlambda博客
学习文章列表

Go语言之父:聊聊我眼中的 Go 语言和环境

大家好,我是煎鱼。

之前春节假期,在家闭关多日。看到了在 2021 年 6 月 Go 语言之父 Rob Pike 在 UNSW Computing(悉尼新南威尔士大学计算机)组织的分享会议,介绍了他对现在 Go 编程语言和环境的一些看法。

今天煎鱼结合大佬的演讲《The Go Programming Language and Environment》和一点个人理解给大家分享一波,包含 Go 发展、生态、看法等多方面知识。

Go 怎么样

Rob Pike 表示其实 Go 目前还不能算做主流语言,但是在全世界的影响力和发展都大大的超出了预期。

像在国内的我们,能够很明显感知到,Go 在近 3~5 年的用户群体不断增大。我早年在 Segmentfault 上发文章,过了 1~2 周,我的 Go 文章,也还在第一页的前几位,发文的人比较稀少,但现在人非常多了。

大家会发现,Go 并不是那种非常 “有趣” 的语言,在技术上(语言理论、设计)几乎没有什么大进步。当然,这也不是 Go 核心团队的设计目标。

但就是这么一门语言,他主导了大部分 CNCF 中的项目,例如:K8s、Docker 等,特别牛。Go 是云基础设施的语言,这是怎么发生的?

Go 为什么成功

Go 从一门无人问津的语言,到现在承担了各云基础设施的核心,变得很重要,也是一种成功实践。

Rob Pike 认为成功的因素有如下:

Go语言之父:聊聊我眼中的 Go 语言和环境

Rob Pike 在 Google 工作时,当时遇到了上述 PPT 截图中的许多问题,像是:软件规模、长期兼容性、应用构建缓慢等许多方面。

核心观点:一门编程语言的成功取决于其他很多方面,Go 语言是面向软件开发的,而不仅仅只是编程。

为此,Go 就是为了解决软件开发而生,而非只是编程,这是成功的关键因素。

Go 要解决的难题

他们遇到的一个大问题就是 Scale(规模),规模又分为了 3 大块问题。

分别是:

  • 并发(Concurrency)。
  • 工程(Engineering)。
  • 依赖(Dependencies)。

并发

在 2007 年,软件规模的扩大的情况下,Google 的生产集群出现了多核 CPU。

当时没有成熟的主流语言可以将多核全部正确使用,导致 Google 即使拥有这些庞大的计算集群,硬件资源的利用率也非常低。

Go语言之父:聊聊我眼中的 Go 语言和环境

线程模型和库很神秘,很复杂,很困难。由于环境的要求,生产代码中不被允许使用线程,而是启动多个二进制文件。

工程

Google 在软件开发上采取的是 Menorepo 的单仓库分包的模式,因此会有成千上万的程序员在同一个代码库中工作,每天都有数不清的变化。

Go语言之父:聊聊我眼中的 Go 语言和环境

但是当时用的都是 C++、Java 等这类语言,太难自动化和分析,很难带来工具的帮助。

依赖

软件规模下的大量依赖,给 Google 带来了很大的麻烦。

Go语言之父:聊聊我眼中的 Go 语言和环境

Java 和 C++的开发速度很慢,C++ 代码的每一个字节都变成了 2000 个字节。

没有办法知道依赖性是否是必要的,感觉是很糟糕的。

Go 初始特性

Go 的大部分核心特性,其实是大佬们在 2007 年 9 月的一个下午,在白板上画了草图和讨论出的。

如下:

Go语言之父:聊聊我眼中的 Go 语言和环境
  • 语法、语义。
  • 并发性。
  • 封装。
  • 垃圾回收。
  • 工具化。
  • 自动化,包括格式化。

接口化

在日常的 Go 程序(标准库、第三方库、应用程序等)中,存在着许多微小的接口,可以让我们做许多的事情,像是写入图片都可以写入到任意地方。

Go语言之父:聊聊我眼中的 Go 语言和环境

这种接口化,也就是常说的鸭子类型(duck typing):像鸭子走路,像鸭子叫(长得像鸭子),那么就是鸭子。

构成了 Go 的应用文化。

类型支持

在类型设计上,Go 与其他编程语言有着很根本的一个差异,那就是不能不同类型混合在一起做运算操作:

Go语言之父:聊聊我眼中的 Go 语言和环境

要跨类型的话,必须做显示转换,不存在明确的隐式转换。

并发

Go 要用协程做并发、并行等动作,非常方便,不需要几行代码。

普通的工程师都能上手:

Go语言之父:聊聊我眼中的 Go 语言和环境
Go语言之父:聊聊我眼中的 Go 语言和环境

这是一个很重要的杀手级特性和卖点。

安全性

在设计时,Go 对安全性考虑了许多。一般来讲,是没法做一些不安全的事情,但硬要做,就必须引用 unsafe 的库:

Go语言之父:聊聊我眼中的 Go 语言和环境

使用 Go 会比 C/C++ 简单许多,既安全又省心。如果出现了 unsafe 的引用,就能明确知道这个程序是 “不安全” 的。

完整性

Go 基于前面所提到的接口化,面向网络、密码学、文本处理、格式化 IO 等实现了一系列的核心基础库:

Go语言之父:聊聊我眼中的 Go 语言和环境

主体指的是 Go 把常用的都覆盖全了,非常高效全面。

一致性

跨系统的编译,只需要稍微调整 2 个环境变量,就可以在 A 系统打出 B 系统能运行的二进制文件,并且行为一致,也不用担心垃圾回收。

Go语言之父:聊聊我眼中的 Go 语言和环境

Rob Pike 还介绍了自己平时都是在 MacOS 下开发,会经常打一个 Linux 的二进制文件部署到服务器上去运行,非常方便。

兼容性

Go 在 2012 年发布 Go1.0 起,就起草了一份 Go1 兼容性保障的文档,以此作为对用户的承诺。将在 Go1 内不会出现破坏性修改,你 10 年前的代码能跑,10 年后也能跑,非常舒服。

Go语言之父:聊聊我眼中的 Go 语言和环境

从现在来看,也是做到了。

开发工具

配套的 Go 开发者工具,是具有标准化的,不像某些语言左一个右一个的,非常混乱。

Go语言之父:聊聊我眼中的 Go 语言和环境

Go 工具链都是 go build、go fmt 等模式。

依赖库

官方有大量的标准库提供,用户可以自定义第三方库。依赖的管理方式是非集中式的,可以在每个人的 URL(例如:GitHub 等),不存在抢占注册的风险。

Go语言之父:聊聊我眼中的 Go 语言和环境

有一点遗憾的是,在早期库依赖时,理论上但就应该包含模块的依赖管理。但当时没有做到,现在有了,也算是 OK 了。

主题

如果希望把 Go 这门语言的生态系统做起来,就要在社区中运转,能够让其他人做出贡献。

Go语言之父:聊聊我眼中的 Go 语言和环境

这里最常见的就是 IDE 的各种 Go 插件,以及平时我们正在使用的第三方库,他人开发的工具等,都可以拿来就用。

文化

Go 社区文化的构建,本质上 Go 现在作为云原生应用的基础,构建了现代的云环境,是由社区主动发起的。

Go语言之父:聊聊我眼中的 Go 语言和环境

共同维护更美好的愿景,一种安全、兼容、可移植性和可读性的文化。

总结

在设计一门语言时,不单单只是设计他,必须要培养他,把其身边的生态系统都做起来,让他变得繁荣。

Go语言之父:聊聊我眼中的 Go 语言和环境

像是 Go,快速、高效、可移植性、部署简单、长期兼容、简单抽象、好用工具、容易测试、容易自动化、很好用的依赖库等。这些东西共同构成了他的文化,也会使他做的更好。

Rob Pike 表示:Go 是关于软件开发的,而不仅仅是编程,这是 Go 的核心精神和理念。

一些交流

  1. 泛型:之所以一开始没有放进特性里,是因为不知道怎么会对他感到不舒服,不确定性极高。但经过 10+ 年的努力,现在已经有了一个基本设计和模型,很有可能会打破一切,Rob Pike 也非常好奇后续的效果。

  2. 声明变量:当前声明的方式比较多,甚至有想砍掉一些。

  3. Channel:认真的尝试过把 channel 和 network 协作,但是一直没有找到好的办法。

  4. GOPATH:Go1.14 以前,会是 GOPATH 的原因,是因为几个开发者确实是在 Google 工作,Google 采取的是 Menorepo 的模式,没有分布式模型的原生态。

参考

  • The Go Programming Language and Environment


关注煎鱼,获取业内第一手消息和知识 👇



你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,