AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

我为什么反对使用 Rust?

  • 2020-09-27
  • 本文字数:3409 字

    阅读完需:约 11 分钟

我为什么反对使用Rust?

本文最初发布于 matklad 的个人博客,由 InfoQ 中文站翻译并分享。


我最近读到一篇批评 Rust 的文章,虽然它提出了一堆好观点,但我不喜欢它——这篇文章很容易引起争论。一般来说,我觉得我不能推荐一篇批评 Rust 的文章。这是件有点令人丢脸的事——直面缺点很重要,而且,批评批评者不努力或知识欠缺会错过一些实际上很好的论点。


以下是我反对 Rust 的理由。

不是所有的编程都是系统编程

Rust 是一种系统编程语言。它可以精确控制数据布局和代码的运行时行为,为你提供了最大的性能和灵活性。与其他系统编程语言不同,它还提供了内存安全性——有 Bug 的程序会以定义良好的方式终止,而不是触发未定义的行为(可能是安全敏感的行为)。


然而,在许多(大多数)情况下,我们不需要最好的性能或对硬件资源的控制。在这种情况下,像 Kotlin 或 Go 这样的现代化托管语言提供了不错的速度、令人羡慕的执行时间,并且由于使用垃圾收集器进行动态内存管理而具有内存安全性。

复杂性

程序员的时间非常宝贵,如果你选择 Rust,那么你得准备好花一些时间来学习一些技巧。Rust 社区投入了大量的时间来编写高质量的教程,但是 Rust 语言非常大。即使 Rust 实现能够为你提供价值,你也可能无法投入资源来提高这门语言的专业技能。


Rust 为改善控制所付出的代价是选择麻烦:


struct Foo     { bar: Bar         }struct Foo<'a> { bar: &'a Bar     }struct Foo<'a> { bar: &'a mut Bar }struct Foo     { bar: Box<Bar>    }struct Foo     { bar: Rc<Bar>     }struct Foo     { bar: Arc<Bar>    }
复制代码


在 Kotlin 中,你编写类class Foo(val bar: Bar),然后继续解决你的业务问题。在 Rust 中,你需要做出一些选择,其中一些非常重要,以至于需要专门的语法。


所有这些复杂性的存在都是有原因的——我们不知道如何创建一个更简单的内存安全的低级语言。但并不是所有的任务都需要低级语言来解决。


延伸阅读:为什么 C++避免了“瓦萨”号沉没的命运?(https://www.youtube.com/watch?v=ltCgzYcpFUI)

编译时间

编译时间是所有事情的倍增器。如果一门语言运行速度慢但编译速度快,那么用它编写的程序也可以运行得更快,因为程序员将有更多的时间来做优化!


Rust在泛型困境中有意选择了慢速编译器。这并不是世界末日(最终的运行时性能改进是真的),但它确实意味着,在较大的项目中,你必须竭尽全力才能获得合理的构建时间。


rustc实现了可能是生产编译器中最先进的增量编译算法,但这感觉有点像是在与语言编译模型作斗争。


与 C++不同,Rust 的构建并不是并行的;并行量受依赖图中关键路径的长度限制。如果你有 40 多个 core 需要编译,这就显出来了。


Rust 还缺乏与pimpl惯用语类似的东西,这意味着更改一个 crate 需要重新编译(而不仅仅是重新链接)其所有反向依赖关系。

成熟度

Rust 才五岁,绝对是一门年轻的语言。尽管它的未来看起来很光明,我还是会把更多的钱押在“C 语言 10 年后仍将存在”上,而不是“Rust 语言 10 年后仍将存在”上(参见林迪效应)。如果你编写的软件要用几十年,那么你应该认真考虑选择新技术伴随的风险。(但是请记住,在 90 年代,为银行软件选择 Java 而不是 Cobol 是正确的选择)。


Rust 只有一个完整的实现——rustc编译器。最先进的替代实现mrustc有意省略了许多静态安全检查。目前,rustc只支持一个可用于生产的后端——LLVM。因此,它对 CPU 架构的支持比 C 更窄,C 有 GCC 实现和许多特定于供应商的专有编译器。


最后,Rust 缺乏官方规范。语言参考还在编写中,文档中也没有详细提供所有的实现细节。

替代语言

在系统编程领域,除了 Rust 外,还有其他语言,比较出名的有 C、C++和 Ada。


现代 C++为提高安全性提供了工具指南。甚至有人提议,建立一个类似 Rustlifetime的机制


!与 Rust 不同,使用这些工具并不能保证不出现内存安全问题。但是,如果你已经维护了大量的 C++代码,那么还是检查下,这些代码是否遵循了最佳实践,并借助sanitizers检测安全问题。这很难,但显然比用另一种语言重写要容易得多!


如果你使用 C,则可以使用正式的方法来证明没有未定义的行为,或者只是详尽地测试一切。


Ada 是内存安全的,如果你不使用动态内存(永远不调用free)。


Rust 是成本/安全曲线上一个有趣的点,但不是唯一的点!

工 具

Rust 工具有好有坏。基线工具、编译器和构建系统(cargo),经常被认为是最好的工具。


但是,举例来说,它缺少一些运行时相关的工具(最明显的是堆分析)——如果没有运行时,就很难反映程序的运行时状况!此外,尽管 IDE 支持很不错,但它的可靠性还远远达不到 Java 级别。在如今的 Rust 中,自动对数百万行程序进行复杂的重构是不可能的。

集 成

无论 Rust 的承诺是什么,如今的系统编程世界都是使用 C 语言,由 C 和 C++所占据,这就是事实。Rust 有意避免模仿这些语言——它不使用 C++风格的类或 C ABI。


这意味着,世界之间的整合需要明确的桥梁。这不是无缝的。它们unsafe,总会有点成本,并且需要在语言之间保持同步。虽然分段集成的承诺已经实现,工具也赶上了进度,但在此过程中会出现偶发的复杂性。


一个特别的问题是,Cargo 固执的世界观(这对于纯 Rust 项目来说是件好事),但可能会使它更难与更大的构建系统集成。

性 能

“使用 LLVM”并不是所有性能问题的通用解决方案。虽然我不知道在规模较大时,C++和 Rust 基准测试的性能对比,但是不难想出一组场景,在这些场景中,相对于 C++,Rust 还有一些性能问题没有解决。


最大的问题可能是,Rust 的 move 语义是基于值的(机器代码级的memcpy)。相反,C++语义使用特殊的引用,你可以从中窃取数据(机器代码级的指针)。理论上,编译器应该能够识别副本链;实践中,情况通常并非如此:#57077。一个相关的问题是,没有 placement new——Rust 有时需要从栈复制字节/将字节复制到栈,而 C++可以在适当的位置构造。


有点可笑的是,Rust 的默认 ABI(为使其尽可能高效而不稳定)有时比 C 更糟糕:#26494


最后,虽然从理论上讲,由于 Rust 具有丰富得多的 aliasing 信息,其代码应该更高效,但启用与 aliasing 相关的优化将触发 LLVM Bug 和编译错误:#54878


但是,重申一下,这些都是刻意挑选的例子,可能有失偏颇。例如,std::unique_ptr有一个性能问题,而 Rust 的Box则没有。


一个潜在的更大的问题是,Rust 的定义时检查泛型比 C++表达性差。因此,一些用于提高性能的C++模板技巧无法在 Rust 中使用好的语法进行表达。

不安全的含义

对于 Rust 而言,一个比 ownership&borrowing 更核心的概念可能是unsafe边界。将所有的危险操作都放在unsafe块和函数的后面,并为它们提供一个安全的高层接口,就有可能创建一个同时满足以下两点的系统:


  1. 健壮(非unsafe代码不会导致未定义的行为);

  2. 模块化(不同的unsafe块可以单独检查)。


很明显,在实践中,这种保证是有效的:对Rust代码进行模糊测试,发现隐藏的 panics,避免缓冲区溢出。


但理论上,前景并不乐观。


首先,缺少 Rust 内存模型定义,就不可能正式检查给定的不安全块是否有效。对于“rustc 所做的或可能依赖的事情”和正在开发中的运行时验证器,都只有非正式的定义,而实际的模型是不断变化的。因此,某些地方可能存在一些unsafe代码,这些代码今天还能正常工作,明天就可能被声明失效,并在明年被新的编译器优化破坏掉。


其次,还有一种观点认为,unsafe块实际上并不是模块化的。总之,功能足够强大的unsafe块可以扩展该语言。两个这样的扩展单独使用可能没有问题,但如果同时使用,则会导致未定义的行为:观测性等价和不安全代码


最后,编译器中还有公开的Bug


下面是我特意从清单中删除的一些内容:


  • 经济因素(“招聘 Rust 程序员更困难”)——我觉得“成熟度”一节抓住了问题的本质,它不能简化为鸡和蛋的问题。

  • 依赖关系(“stdlib 太小/所有东西都有太多的依赖”)——考虑到 Cargo 以及语言的相关部分都很不错,我个人并不认为这是一个问题。

  • 动态链接(“Rust 应该有稳定的 ABI”)——我不认为这是一个强有力的论点。从根本上来说,单态化(Monomorphization)与动态链接是不兼容的,如果需要的话,还有 C ABI。我确实认为这里的情况可以改善,但我不认为这种改善是Rust特有的


感兴趣的读者可以点击这里:https://www.reddit.com/r/rust/comments/iwij5i/blog_post_why_not_rust/ ,查看关于本文的讨论。


查看英文原文:


https://matklad.github.io/2020/09/20/why-not-rust.html


2020-09-27 14:3022750
用户头像
陈思 InfoQ编辑

发布了 576 篇内容, 共 279.4 次阅读, 收获喜欢 1301 次。

关注

评论 7 条评论

发布
用户头像
无话可说
2020-09-29 15:00
回复
用户头像
写这篇文章的人垃圾,翻译的也是。你不懂别瞎bb,你所谓不看好,所反对的,并不会影响人家语言的繁荣昌盛。请IT社区不要渲染这种毒鸡汤,挑起没必要的编程语言竞争战斗。谢谢!
2020-09-28 09:55
回复
……翻译得确实烂,但是你连原文也一起喷,说明你其实并没有认真看过原文。这个作者实际上是 Rust 的支持者而不是反对者。他写这篇文章的原因是,他看到了另一篇批评 Rust 的文章,但他觉得那篇文章没批评到点子上,于是他写了这篇文章告诉大家 Rust 真正的缺点在哪里。
2020-09-30 03:41
回复
其实他的批评不无道理,一味的扣帽子解决不了争议,相反,大家把合理的问题说出来才是有益的
2020-10-02 00:10
回复
用户头像
垃圾
2020-09-28 09:53
回复
用户头像
保守派,好多大公司都在试用Rust了。
2020-09-27 14:55
回复
你得看场景,目前MS,Apple在用的都是非常特定的场景,不是那种体量的企业确实有必要斟酌一下必要性的问题
2020-10-02 00:11
回复
没有更多了
发现更多内容

Spring Boot 2.0 实现优雅停机

U2647

Spring Boot 4月日更

用户故事是垂直的切片(译)

Bruce Talk

敏捷 译文 Agile User Story

今年我读了四个开源项目的源码,来分享下心得

yes

源码

区块链电子证据的司法应用现状与展望

CECBC

HBase HA 分布式部署

Fong

大数据 运维 HBase hadoop3

如何从零开始学Python:(4)如何处理列表数据?

广之巅

Python 4月日更

Properties类使用需要注意的坑

风翱

properties 4月日更

Golang 并发

escray

学习 极客时间 Go 语言 4月日更

没有自信的人,才会在意别人的评价

小天同学

心理 日常思考 个人感悟 4月日更 自信

用户故事拆分招数全景图(译)

Bruce Talk

敏捷 译文 Agile User Story

《专访彩食鲜CTO乔新亮:体系的重要性》(采访提纲)

花花

调查采访能力考核

专访声网首席资深iOS研发工程师龚宇华:从自学计算机到高级架构师

黑马腾云

专访

实体经济与数字经济加速融合 中国经济新动能快速成长

CECBC

数字经济

python内置数据结构list、set、dict、tuple(一)

若尘

List 数据结构 set 字典 Python编程

《采访阿里“守护神”吴翰清:安全攻防-采访提纲》

Geek_6370d5

【采访融云CTO杨攀:2021如何让融云迈向更高舞台】(采访)

洛神灬殇

融云 杨攀

翻译:《实用的Python编程》TheEnd

codists

Python

不忘初心,砥砺前行|暨InfoQ写作平台一周年

程序员架构进阶

28天写作 4月日更 1 周年盛典 我和写作平台的故事 InfoQ 写作平台 1 周年

网络安全传奇吴翰清采访提纲 |调查采访能力考核

清秋

网络安全 签约计划 调查采访能力考核

禁止算法识别性别,能消解歧视吗?

脑极体

白皮书:区块链将成隐私计算产品必选项,提供三方面助力

CECBC

区块链

重读《重构2》- 以对象取代基本类型

顿晓

重构 4月日更

为什么 Serverless 将推动边缘计算的革命

公众号:云原生Serverless

Serverless 边缘计算

Ansible 配置

耳东@Erdong

4月日更

浅谈Javascript中的forEach和map之间的区别

devpoint

遍历 foreach map reduce

全网最强的权限系统设计攻略:京东北极星商业系统权限管控实践

学Java关注我

Java 编程 程序员 架构 技术宅

分库分表笔记

luojiahu

分库分表

架构实战营 模块2作业

CR

炫彩无界,性能怪兽,M1 扛鼎未来 —— 2021 年 Apple 春季新品发布会全记录

清秋

产品 苹果 硬件 新闻

如何做好前馈管理?

石云升

28天写作 职场经验 管理经验 4月日更

专访吴翰清 || 如何用网络安全保障个人隐私

Bob

网络安全 个人隐私 调查采访能力考核

我为什么反对使用Rust?_编程语言_matklad_InfoQ精选文章