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 认为成功的因素有如下:
Rob Pike 在 Google 工作时,当时遇到了上述 PPT 截图中的许多问题,像是:软件规模、长期兼容性、应用构建缓慢等许多方面。
核心观点:一门编程语言的成功取决于其他很多方面,Go 语言是面向软件开发的,而不仅仅只是编程。
为此,Go 就是为了解决软件开发而生,而非只是编程,这是成功的关键因素。
Go 要解决的难题
他们遇到的一个大问题就是 Scale(规模),规模又分为了 3 大块问题。
分别是:
并发(Concurrency)。 工程(Engineering)。 依赖(Dependencies)。
并发
在 2007 年,软件规模的扩大的情况下,Google 的生产集群出现了多核 CPU。
当时没有成熟的主流语言可以将多核全部正确使用,导致 Google 即使拥有这些庞大的计算集群,硬件资源的利用率也非常低。
线程模型和库很神秘,很复杂,很困难。由于环境的要求,生产代码中不被允许使用线程,而是启动多个二进制文件。
工程
Google 在软件开发上采取的是 Menorepo 的单仓库分包的模式,因此会有成千上万的程序员在同一个代码库中工作,每天都有数不清的变化。
但是当时用的都是 C++、Java 等这类语言,太难自动化和分析,很难带来工具的帮助。
依赖
软件规模下的大量依赖,给 Google 带来了很大的麻烦。
Java 和 C++的开发速度很慢,C++ 代码的每一个字节都变成了 2000 个字节。
没有办法知道依赖性是否是必要的,感觉是很糟糕的。
Go 初始特性
Go 的大部分核心特性,其实是大佬们在 2007 年 9 月的一个下午,在白板上画了草图和讨论出的。
如下:
语法、语义。 并发性。 封装。 垃圾回收。 工具化。 自动化,包括格式化。
接口化
在日常的 Go 程序(标准库、第三方库、应用程序等)中,存在着许多微小的接口,可以让我们做许多的事情,像是写入图片都可以写入到任意地方。
这种接口化,也就是常说的鸭子类型(duck typing):像鸭子走路,像鸭子叫(长得像鸭子),那么就是鸭子。
构成了 Go 的应用文化。
类型支持
在类型设计上,Go 与其他编程语言有着很根本的一个差异,那就是不能不同类型混合在一起做运算操作:
要跨类型的话,必须做显示转换,不存在明确的隐式转换。
并发
Go 要用协程做并发、并行等动作,非常方便,不需要几行代码。
普通的工程师都能上手:
这是一个很重要的杀手级特性和卖点。
安全性
在设计时,Go 对安全性考虑了许多。一般来讲,是没法做一些不安全的事情,但硬要做,就必须引用 unsafe 的库:
使用 Go 会比 C/C++ 简单许多,既安全又省心。如果出现了 unsafe 的引用,就能明确知道这个程序是 “不安全” 的。
完整性
Go 基于前面所提到的接口化,面向网络、密码学、文本处理、格式化 IO 等实现了一系列的核心基础库:
主体指的是 Go 把常用的都覆盖全了,非常高效全面。
一致性
跨系统的编译,只需要稍微调整 2 个环境变量,就可以在 A 系统打出 B 系统能运行的二进制文件,并且行为一致,也不用担心垃圾回收。
Rob Pike 还介绍了自己平时都是在 MacOS 下开发,会经常打一个 Linux 的二进制文件部署到服务器上去运行,非常方便。
兼容性
Go 在 2012 年发布 Go1.0 起,就起草了一份 Go1 兼容性保障的文档,以此作为对用户的承诺。将在 Go1 内不会出现破坏性修改,你 10 年前的代码能跑,10 年后也能跑,非常舒服。
从现在来看,也是做到了。
开发工具
配套的 Go 开发者工具,是具有标准化的,不像某些语言左一个右一个的,非常混乱。
Go 工具链都是 go build、go fmt 等模式。
依赖库
官方有大量的标准库提供,用户可以自定义第三方库。依赖的管理方式是非集中式的,可以在每个人的 URL(例如:GitHub 等),不存在抢占注册的风险。
有一点遗憾的是,在早期库依赖时,理论上但就应该包含模块的依赖管理。但当时没有做到,现在有了,也算是 OK 了。
主题
如果希望把 Go 这门语言的生态系统做起来,就要在社区中运转,能够让其他人做出贡献。
这里最常见的就是 IDE 的各种 Go 插件,以及平时我们正在使用的第三方库,他人开发的工具等,都可以拿来就用。
文化
Go 社区文化的构建,本质上 Go 现在作为云原生应用的基础,构建了现代的云环境,是由社区主动发起的。
共同维护更美好的愿景,一种安全、兼容、可移植性和可读性的文化。
总结
在设计一门语言时,不单单只是设计他,必须要培养他,把其身边的生态系统都做起来,让他变得繁荣。
像是 Go,快速、高效、可移植性、部署简单、长期兼容、简单抽象、好用工具、容易测试、容易自动化、很好用的依赖库等。这些东西共同构成了他的文化,也会使他做的更好。
Rob Pike 表示:Go 是关于软件开发的,而不仅仅是编程,这是 Go 的核心精神和理念。
一些交流
泛型:之所以一开始没有放进特性里,是因为不知道怎么会对他感到不舒服,不确定性极高。但经过 10+ 年的努力,现在已经有了一个基本设计和模型,很有可能会打破一切,Rob Pike 也非常好奇后续的效果。
声明变量:当前声明的方式比较多,甚至有想砍掉一些。
Channel:认真的尝试过把 channel 和 network 协作,但是一直没有找到好的办法。
GOPATH:Go1.14 以前,会是 GOPATH 的原因,是因为几个开发者确实是在 Google 工作,Google 采取的是 Menorepo 的模式,没有分布式模型的原生态。
参考
The Go Programming Language and Environment
关注煎鱼,获取业内第一手消息和知识 👇
你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路。
日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!