写点什么

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

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

关注

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

万界星空科技云MES,助力客户快速构建数字工厂

万界星空科技

mes 万界星空科技 低代码云MES

APP加固技术及其应用

雪奈椰子

程序员都必须知道的Vue 开发技巧

不在线第一只蜗牛

vue.js Vue 开发技巧

Avdshare Audio Converter for Mac(性能超强的音频格式转换器)

Rose

苹果软件下载 Avdshare Audio Converter Mac音频格式转换器

2023年国内AI Agent下项目大盘点,科技大厂与创业公司齐头并进

王吉伟频道

创业 融资 大语言模型 AI Agent AI智能体

关于 IntelliJ IDEA 中 Schedule for Addition 的问题

Rose

IntelliJ IDEA

去年最火的 JS 开源项目「GitHub 热点速览」

EquatorCoco

GitHub 开源 js 工具库

矢量图形转换工具vector magic for Mac 兼容macos14系统

Rose

mac软件下载 Vector Magic破解版 矢量图像转换工具

实时获取建材网商品数据:API实现详解与代码示例

Noah

GaussDB(for MySQL)新特性TDE发布:支持透明数据加密

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 华为云GaussDB(for MySQL)

NFTScan | 01.01~01.07 NFT 市场热点汇总

NFT Research

NFT NFT\ NFTScan

OpenAI 也在 996?一位离职员工自白:代码贡献第四,经常工作 6 天丨 RTE 开发者日报 Vol.121

声网

TikTok海外直播专线:优化你的海外直播体验

Ogcloud

直播 直播优化 TikTok

软件测试开发/全日制/测试管理丨接口功能测试

测试人

软件测试 自动化测试 接口测试 测试开发 测试管理

2024年最热门的15个科技工作岗位

互联网工科生

程序员 科技 岗位

5分钟使用Hologres实时湖仓加速分析挑战赛来袭

阿里云大数据AI技术

AudFree Tidable Music Converter for Mac(Tidal音乐转换器)

Rose

Tidal音乐转换器 苹果电脑音频转换器 AudFree Tidal Music

MongoDB 数据库管理和开发Navicat for MongoDB【Mac/win】

Rose

MongoDB数据库 Navicat数据库下载 Navicat for MongoDB中文

AE脚本-快速创建微风摇曳摆动波浪动画 Breeze

Rose

AE脚本-图层分布路径形状高级控制 Tweaks

Rose

LED屏租赁需求激增,为何LED显示屏租赁如此受欢迎?

Dylan

综艺节目 应用 LED显示屏 户外LED显示屏 led显示屏厂家

Mac电脑前端代码编辑神器:Sublime Text 4 Dev 激活码中文

mac大玩家j

代码编辑器 Mac软件 前端代码编辑器

如何查看崩溃日志

PostgreSQL数据库开发工具Navicat for PostgreSQL中文版

Rose

数据库设计 Navicat for PostgreSQL PostgreSQL数据库开发

[Mac/win数据库最新版]Navicat for MySQL 永久激活教程

Rose

Navicat for MySQL 数据库管理开发 Navicat数据库软件下载

强大的原型设计:Kite Compositor最新激活版

胖墩儿不胖y

Mac软件 原型设计工具 Mac动画软件

做CAE分析用哪个显卡?CAE咨询

思茂信息

仿真 CAE CAE软件

macos强大的界面设计和原型制作工具:Kite

Rose

Mac动画原型设计 Kite for Mac破解 Kite Mac下载 苹果软件下载站

阿里云 EMAS & 魔笔:12月产品动态

移动研发平台EMAS

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