阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

我为什么反对使用 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:3021955
用户头像
陈思 InfoQ编辑

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

关注

评论 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
回复
没有更多了
发现更多内容

HTTP/2做错了什么?刚刚辉煌2年就要被弃用了

学Java关注我

Java 编程 架构 程序人生 计算机

15个问题告诉你如何使用Java泛型

华为云开发者联盟

Java 接口 参数 Java泛型 泛型对象

anyRTC 智能硬件解决方案

anyRTC开发者

音视频 WebRTC IoT 智能硬件

如何基于 PANO SDK 实现 iOS 端屏幕共享互动

拍乐云Pano

ios sdk

可能有点长的Spring MVC入门篇

北游学Java

Java spring ssm Spring MVC

阿里云 RTC QoS 弱网对抗之 LTR 及其硬件解码支持

阿里云视频云

阿里云 音视频 WebRTC 视频解码 视频云

【InfoQ 写作平台 1 周年】我和写作平台剪不断的“孽缘”

三掌柜

征稿 InfoQ 写作平台 1 周年

索引的正确“打开姿势”

华为云开发者联盟

数据库 索引 B-tree Psort 分区

探讨 JS 对象如何缓存属性的值

零维

JavaScript 大前端 设计模式

关于软件IT专业大学生对专业认知情况的调查问卷

花花

签约计划

面向软件 IT 专业的高校大学生职业思考调查问卷

程序员架构进阶

职业规划 调查报告 就业 28天写作 4月日更

大学生IT就业方向以及就业培训的调查问卷

麦洛

调查报告 调查采访能力考核 问卷调查

Worktile 权限设计与实现

PingCode研发中心

项目管理 后端 权限管理

鸿蒙系统(HOS)终于上线,微内核操作系统科普

北游学Java

Java 操作系统 微内核

五一啃透这份阿里巴巴Java面试指导手册(泰山版),节后直接面试找工作!

Java架构追梦

Java 阿里巴巴 架构 面试 泰山版

IT之家专访庄秉翰:未来全球5G vRAN将达90%,英特尔5G布网参与度非常高

E科讯

水性硅胶防滑透明浆

C13713145387

安全知识

笑春风

Windows系统下电脑强制卡死、关机的邪恶方法

不脱发的程序猿

程序人生 技术人 4月日更 系统关机 计算机小技巧

如何构造更好的团队

soolaugust

团队管理 架构

IT专业本科生毕业选择【就业】/【攻读硕士】调查问卷

Aldeo

考核 大学生毕业 问卷调查

10行C++代码实现高性能HTTP服务

万俊峰Kevin

c c++ workflow Open Source

五一小长假最新产物:阿里巴巴面试的参考指南(泰山版)

学Java关注我

Java 编程 程序员 架构 计算机

软件IT专业大学生就业意向问卷调查

三掌柜

签约计划 问卷调查

视频后期怎么添加AR贴图?一招教你搞定!

奈奈的杂社

视频剪辑 视频后期 剪辑 会声会影

为什么越来越多的人不敢结婚?

徐说科技

婚姻 情感 恐婚

精彩3000字!给讲得明明白白:配置 logback

比伯

Java 编程 程序员 架构 计算机

大学生读书情况调研

hepingfly

读书 调研 大学生 阅读

圆梦阿里之后,我收集整理了这份“2021春招常见面试真题汇总”

比伯

Java 编程 架构 程序人生 计算机

网易云课堂个性化推荐实践与思考

有道技术团队

推荐系统

政采云:数据可视化探索之SpreadJS 表格控件

葡萄城技术团队

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