本文摘选和整理自 De Programmatica Ipsum 月刊的一篇由 Adrian Kosmaczewski 于 2021 年 3 月 3 日发表的文章 The Great Rewriting In Rust、Geoffroy Couprie 个人站点文章 Why you should, actually, rewrite it in Rust,以及 ansuz/RIIR 项目文章 Have you considered Rewriting It In Rust?。其中后两篇文章比较早了,朋友们可以直接略过,了解有这么个因果即可。
De Programmatica Ipsum 是一本月刊,由 Graham Lee 和 Adrian Kosmaczewski 合作主编,自称是“两个脑子被烧坏了的老家伙,呼喊着冲向 void *”。这个月刊介绍软件工程的工艺、软件开发人员的生活;重点关注程序员生活中的包容、倦怠/疲惫、创业生活;另外,此月刊也乐于炒作,以及一些不合常理,甚至“异端邪说”的话题——比如上面提到的文章。
关于安全编程
2002 年,微软出版社出版了 David LeBlanc 和 Michael Howard 合著的书籍,《编写安全代码(Writing Secure Code),第二版》。此书曾是微软的必读书目,紧随着比尔·盖茨(Bill Gates)的“可信计算(Trustworthy Computing)”备忘录。《编写安全代码(Writing Secure Code),第二版》的第五章题为“第 1 号公敌:缓冲区溢出(Buffer Overrun)”,它从一个非常有趣的历史角度出发,阐述如何编写安全代码,防范缓冲区溢出。书中以 1986 年的莫里斯蠕虫(Morris Worm)为例,甚至可以追溯到 20 世纪 60 年代。
C 语言,通常被称为“可移植汇编(portable assembly)”,没有提供任何防范这种“公敌”的措施。如果你错误地(或有意地)分配了 N 字节的内存,但又写了 N k(其中 k 是一个严格大于零的无符号整数)。那么,几乎会必然导致缓冲区溢出。比起修复 bug,你还不如重写正在运行的软件。
可以说,缓冲区溢出导致过行业数十亿美元的损失,每一代计算机科学家都为解决这个问题提出了新的想法。曾经寄希望于托管代码和 .NET
框架。关于此,《编写安全代码(Writing Secure Code),第二版》一书第 18 章是以一个轶事开始的:
在 2001 年 11 月的微软专业开发者大会上,我为两篇安全软件论文制作幻灯片时,一位朋友告诉我,我很快就会失业。因为一旦托管代码和
.NET
框架发布,所有的安全问题都会消失。这使我把 SQL 注入演示代码,从 C 转换成 C 语言,以证明他错了。
啊,软件从业人员!
安全编程方面,也曾将希望寄予 Java 和 C#,数以百万计的应用程序和数十亿行代码,被一次又一次地用这些现代编程语言重写。虽然 Joel Spolsky、Steve Blank,以及 Peter Seibel 都阐述过重写软件这种做法的愚蠢,重写软件也在圈子内被广泛嘲笑。但是,在软件行业里面,重写软件仍然是一项乐此不疲的运动。
各时代的编程语言
回顾过去,每一个十年,都有自己时代选择的编程语言,世界被一次又一次地改写。
- 20 世纪 60 年代:Fortran(因为 IBM!)
- 20 世纪 70 年代:BASIC(因为 Byte Magazine!)
- 20 世纪 80 年代:Pascal(因为结构化编程!)
- 20 世纪 90 年代:C (因为面向对象!)
- 21 世纪初:Java(因为万维网!)
- 2010 年:JavaScript(因为……啥原因?!)
我们来玩预测游戏,哪一个编程语言将是 21 世纪 20 年代的选择,也就是说,世界将被哪一个编程语言改写?
显然不是 Java、C#、F#、Dart、Swift,或者 Kotlin。
是 Go 吗?显然不是,因为它在某种程度上被限制了,仅限于创造本地云工具或独立的跨平台命令行程序。
Rust 将改写世界
经过仔细分析,20 世纪 20 年代,时代选择的语言可能是(也许已经是)Rust。这是一门罕见的,能让软件程序员和硬件程序员都满意的语言。
Rust 显示了许多迹象(非全部):
- 开源的,托管在 github,我们都知道:开放者总会胜利(open always wins)。
- 具备泛型特性,这是解决霍尔难题的基础选项(译注:托尼·霍尔,Tony Hoare,快速排序算法、霍尔逻辑、交谈循序程式设计者,图灵奖得主)。
- 没有继承(inheritance)特性,而是由
trait
组合(composition)。 - 不依赖异常来处理错误,而是
Result
泛型类型。 - 没有垃圾收集器,而是在编译期间控制引用生命周期和所有权。
- 包括流行的功能性编程结构,如:lambdas、map/filter/reduce,甚至做的更好。
- 免费图书,以及在线演练。不必在本地计算机上安装任何东西,就可以学习 Rust。
- 即使为了使代码看起来像脚本,而使用了类型推断,但 Rust 有一个强大的类型系统,可以在编译时解决缓冲区溢出问题。
- 可以通过
curl
脚本安装在任何终端。 - 现成的算法和抽象库,以“自带电池”的方式吸引了系统和应用程序开发人员。
- 具有内置功能单元测试.
- 变量在默认情况下是不可变的。
- Rust 宏,C 语言宏的智能进化,混合了 C 模板元编程。
- 数组,将长度作为其类型的一部分,可以很容易地在同一处初始化。
- 编译器生成非常高效的代码,并且可以进行交叉编译。甚至可以生成独立的静态链接二进制文件,准备在 Docker 容器中使用。
- 有年度开发者大会,名为 RustConf,有专有的 Rust 官方周报;有专有的 Awesome Rust 页面,在 Stack Overflow 上有很多问题和答案。
- 使用大括号,并且
rustfmt
工具消除了因样式而造成代码冲突的风险。 goto
不是关键词,尊重迪杰斯特拉( Dijkstra)戒律。- ……
简而言之,Rust 会成为时代的选择。
Rust 生态系统
让我们来看看 Rust 在各个行业的使用。
- Mozilla(Rust 创造者)用 Rust 重写旗舰浏览器。
- Linus Torvalds 确信 Rust 将接管 Linux 内核。同时,很多公司都在用 Rust 重写其软件或者游戏,如 coreutils(GNU)、alacritty(OpenGL)、……,甚至包括 LaTeX。
- 微软,在“可信计算”演示后的 20 年,仍然认为内存安全问题占所有安全漏洞的 70%。因此 Rust 是目前安全系统编程的最佳机会。微软对 Rust 的兴趣如此之大,以致于它加入 Rust 基金会,促进 Rust 成为在 Kubernetes 上的应用程序的可靠替代方案。
- 谷歌正在将 Rust 推向安卓(用于重写蓝牙部分),及其 Linux 内核。Rust 也用在谷歌的新操作系统 Fuchsia。
- 英特尔说 Rust 是“系统编程的未来”。
- 亚马逊使用 Rust 建造 AWS Firecracker 系统。
- Dropbox 使用 Rust 重写它的同步引擎。
- 苹果招聘了大量 Rust 工程师。
- JetBrains 有支持 Rust 的IDE 插件(vsCode 也有,eclipse、vim 等同样有)。
- IBM 开发者网站一直在进行 Rust 教授。
- Stack Overflow,Rust 语言连续 5 年在“最想学语言排行榜”位列榜首。
- Discord 切换到 Rust 语言。
- Figma 在生产环境中,将 Rust 引入后端产品。
- 云应用中,Linkerd(Rust 开发)比 Istio(Go 开发)更高效和受欢迎。
- 甚至 JavaScript 和 npm 都正在使用 Rust 重建。
- Python 和 Rust 的互操作已经较为成熟。
- 有人在忙于开发 Java 和 Rust 的互操作。
- 有人在忙于开发 .net 和 Rust 的互操作。
- ……
即使不是所有人抱有同样的热情,但很明显,这些事情是潮流,并非 Rust 在炒作。
RIIR(Rewrite It In Rust),用 Rust 重写它
你可能经常在博客上、在 github issues 中、在朋友圈等地方看到一些“讨厌的”言论——用 Rust 重写它?现在,在 github 上 有个项目称作 RIIR(Rewrite It In Rust,用 Rust 重写它),星星数 300 左右;也有其 twitter 账户。另外,本文开头提到的后 2 篇文章中,阐述用 Rust 重写的合理性、可能性,以及示范先行项目。
说这个项目是个玩笑,但又有那么些真实性。毕竟现在,不少公司真的在用 Rust 重写一些久远的软件。
结语
Rust 会解决今天的一些问题,比如安全编程相关。同时,我们也需要明白,虽然目前无法预料,但 Rust 也会带来新的问题。
让时间来验证吧!
谢谢您的阅读,欢迎交流。