免费下载案例集|20+数字化领先企业人才培养实践经验 了解详情
写点什么

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

发布了 576 篇内容, 共 275.8 次阅读, 收获喜欢 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
回复
没有更多了
发现更多内容

Amazon EC2 云服务器体验感爆了

归来

Amazon EC2 云服务器

CNCC 2023 | 大模型全面革新推荐系统!产学界多位大咖精彩献言

小红书技术REDtech

算法 推荐系统 多模态 大模型 内容理解

Amazon EC2 Hpc7g 实例现已在更多区域推出

亚马逊云科技 (Amazon Web Services)

Amazon EC2

企业该如何选择数字化转型工具?

优秀

数字化转型 数字化工具

大语言模型“战国时代”,未来将如何发展?

申屠鹏会

AI大语言模型

轻量应用服务器:现代云计算的宝贵利器

E₀=mc²

云计算 虚拟化 亚马逊云科技 VPS

Linux Vim批量注释和自定义注释

芯动大师

Windows、Linux 和 Mac三个操作系统的对比

小魏写代码

软件测试/测试开发丨Python安装指南(Windows版)

测试人

Python 软件测试

向量数据库的崛起与多元化场景创新

向量数据库

罗拉ROLA住宅代理IP市场稳定增长,未来有哪些发展前景?

Geek_ccdd7f

一种Mysql和Mongodb数据同步到Elasticsearch的实现办法和系统

天翼云开发者社区

MySQL 数据库

深入Vue.js与TypeScript的生命周期

K8sCat

vue.js 生命周期

项目管理从混乱到井然有序,就差这10款看板软件了!

彭宏豪95

项目管理 效率工具 项目经理 在线白板 看板工具

搭建二维码系统,轻松实现固定资产的一物一码管理

草料二维码

投资机构Janus Capital Group为Rola-IP品牌融资700万美元

Geek_ccdd7f

人大金仓三大兼容:SQL Server迁移无忧

科技热闻

快速实现一个企业级域名 SSL 证书有效期监控巡检系统

观测云

监控告警 智能巡检 SSL域名

sip中继是什么意思

cts喜友科技

SIP

私域流量搭建与运营,全是技巧攻略!

鲸品堂

运营 流量 企业号11月PK榜

用了低代码工具,让我效率提升了80%

树上有只程序猿

软件开发 低代码开发平台 JNPF

第26期 | GPTSecurity周报

云起无垠

一站式解决方案:体验亚马逊轻量服务器的顶级服务与灵活性

-亦世凡华、

跨语言高性能RPC框架Focus发布V1.1.0

dinstone

RPC 高性能 跨语言 RPC框架

文心一言 VS 讯飞星火 VS chatgpt (129)-- 算法导论11.1 4题

福大大架构师每日一题

福大大架构师每日一题

瓴羊重磅发布数据服务枢纽“瓴羊港”,推动企业数据流通及价值增长

B Impact

这可能是全网最晚的低代码技术总结

互联网工科生

低代码 低代码平台

sip中继的介绍

cts喜友科技

SIP

李开复带领零一万物,新一轮融资由阿里云领投,估值超10亿美元

B Impact

Python 文件处理指南:打开、读取、写入、追加、创建和删除文件

小万哥

Python 程序员 软件 后端 开发

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