来QCon北京,现场感受“纯血鸿蒙”的魅力!席位有限,抓紧报名 了解详情
写点什么

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

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

RabbitMQ详解——RabbitMQ架构部署(四)

BeyondLife

RabbitMQ Mirror Queue Federation

《个保法》施行 | App 隐私合规检测双十一尝鲜仅需99元

蚂蚁集团移动开发平台 mPaaS

隐私保护 移动开发 监管合规

百度Apollo参编首批汽车信息安全国家标准,跻身车联网信息安全第一梯队

百度开发者中心

Apollo

Github上线仅六天,收获Star超55K+,这套笔记能拿下90%以上面试

Java redis spring 程序员 架构

能让你从P6+学到P9也只有马士兵老师了,全套学习资源分享

Java架构追梦

Java 编程 架构 面试 马士兵

看企业如何玩转低代码,引发效率革命

行云创新

云原生 低代码 开发 直播 双十一

iOS开发-百度一面总结

iOSer

ios 面试 iOS面试 ios开发 百度面试

“智慧粮仓”守卫中国饭碗

ThingJS数字孪生引擎

大前端 物联网 可视化

你需要知道的 19 个 console 实用调试技巧

CRMEB

CSS JavaScript DOM console crmeb

【等保小知识】等保与分保的三大区别汇总分析

行云管家

网络安全 数据安全 等保 分保

初入云计算行业,可以考取哪些云计算证书?

行云管家

云计算 腾讯云 阿里云 证书 IT运维

linux 设置VPN

webrtc developer

Linux vpn

2022第十五届北京国际智慧城市、物联网、大数据博览会

InfoQ_caf7dbb9aa8a

Vue进阶(幺陆肆):自定义指令之拖拽指令

No Silver Bullet

Vue 11月日更

腾讯安全姬生利:云原生环境下的“密码即服务”

腾讯安全云鼎实验室

云原生 加密

学长带路学吉他,这几招足够了

懒得勤快

托管页前端异常监控与治理实战

百度Geek说

大前端

超全整理:程序员都在用什么工具?

华为云开发者联盟

程序员 技术 设计 编程语言 开发工具

华为云·核心伙伴开发者训练营——产业云专场在东莞松山湖圆满落幕

华为云开发者联盟

华为云 鲁班会

顶会VLDB‘22论文解读:CAE-ENSEMBLE算法

华为云开发者联盟

算法 时间序列 华为云数据库 深度神经网络

RabbitMQ详解——服务端存储机制(二)

BeyondLife

RabbitMQ mnesia ETS

Node.js 17 新特征简介

devpoint

node.js Promise 11月日更

GitHub点击量破百万访问,不愧是被称阿里神作的JDK源码笔记

Sakura

Java 源码 架构 jdk 面试

《黑客之道》kali Linux之NMAP高级使用技巧和漏洞扫描发现

学神来啦

Linux 渗透 kali nmap

网课录屏用什么软件好?Camtasia极简操作,课程重点一目了然

淋雨

Camtaisa

数据库审计是什么意思?作用是什么?

行云管家

数据库 安全 IT运维 数据库审计

架构实战营模块七作业

Geek_d18264

架构实战营

华为云天筹AI求解器:智能世界是道迷人的数学题

脑极体

恒源云(GPUSHARE)_CAN: 借助数据分布提升分类性能

恒源云

深度学习

四种 AI 技术方案,教你拥有自己的 Avatar 形象

阿里云视频云

人工智能 阿里云 计算机视觉 视频云 元宇宙

百度鸿鹄芯片落地首款量产车吉利博越X 智能车机体验惊艳成都车展

百度开发者中心

百度 车联网 鸿鹄芯片

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