干货分享|Rust“巨坑”?真相来了!
发布时间:2023-08-17 14:01:31
Rust 是一门极具争议性的语言。有许多创业公司的开发者甚至创始人都点名表示:Rust 是巨坑!简直浪费时间。再比如,其他语言中的“粗糙编码”的编程方式在 Rust 中也很难实现;库和文档也不够成熟,学习起来相当费劲,诸如此类。
但总的来说,在强调“安全性比开发生产力更重要”的今天,Rust 从来没有失去成为一种未来语言的资格。虽然正视缺点很重要,但有些草率的批评也许未必是真相,或者说是不准确的。
今天将为大家展示“不偏不倚”的 Rust 的真实特性。
1、并非所有开发都是系统编程
2、语言复杂性
漫长的编译时间往往会压垮每一位程序员。用运行速度较慢但编译速度较快的编程语言编写的代码,通常更有机会运行得更快,因为程序员有更多时间来优化代码。
Rust 在通用性难题中故意选择了缓慢的编译器。这不一定是世界末日(因为由此产生的运行时性能增益是真实的),但这确实意味着在较大的项目中,开发者将不得不努力争取合理的构建时间。
rustc 实现了生产编译器中可能最先进的增量编译算法,但这感觉有点像与语言编译模型作斗争。
与 C++ 不同,Rust 构建并没有笨拙地并行化,并行度受到依赖图中关键路径长度的限制。如果有 40 个以上的内核进行编译,则会显示此信息。
Rust 还缺乏类似 pimpl 的功能,这意味着更改 crate 需要重新编译(不仅仅是重新链接)其所有反向依赖项。
4、相对年轻的语言
Rust 只有 8 年的历史,相较而言,Rust 还算一门年轻的语言。创建这个新语言的目的是为了解决一个顽疾:软件的演进速度大大低于硬件的演进,软件在语言级别上无法真正利用多核计算带来的性能提升。
根据林迪效应,相信“C++ 将在未来十年内存在”的人要远多于对“Rust 将在十年内存在”的人。同样地,如果你编写的软件可以使用数十年,在选择新技术之前,往往会再三考虑与之相关的风险。
但慎重考虑并不代表放弃新技术。一个过去的案例就是,在 90 年代为银行软件选择 Java 而不是 Cobol 事实证明是正确的选择)。
Rust 目前只有一种完整的实现——rustc 编译器。另一个最佳替代实现,mrustc,有意省略了许多静态安全检查。rustc 目前仅支持一种生产就绪后端 - LLVM。因此,它对 CPU 架构的支持范围比 C 语言更窄,后者具有 GCC 实现以及许多特定于供应商的专有编译器。
最后,Rust 缺乏官方规范。参考文档正在开发中,尚未记录实现的所有细节。
5、可替代性
在系统编程领域,除了 Rust 之外,还有其他一些语言,主要是 C、C++ 和 Ada。
现代 C++ 提供了提高安全性的工具和指南,甚至有人为 C++提出了类似 Rust 的生命周期机制。但与 Rust 不同,使用这些工具并不能保证没有内存安全问题。但是,如果你已经维护了大量 C++ 代码,那么检查以下最佳实践和使用清理程序是否有助于解决安全问题是有意义的。这很困难,但显然比用另一种语言重写它要容易。
如果你使用 C,你可以使用形式化方法来证明不存在未定义的行为,否则你只能详尽地测试一切。如果不使用动态内存(切勿调用 free),Ada 是内存安全的。
Rust 偏偏是成本/安全曲线上的一个有趣的权衡点,但肯定不是唯一的不可替代的点。
6、工具
Rust 工具是值得点赞叫好的。基线工具、编译器和构建系统(cargo)通常被认为是一流的。
但是,例如,一些与运行时相关的工具(尤其是堆分析)目前还不存在——如果没有运行时工具,就很难分析程序的运行时。此外,虽然 IDE 支持不错,但它还远未达到 Java 级别的可靠性。如今,在 Rust 中不可能自动复杂地重构数百万行程序。
7、性能
“使用 LLVM”并不是解决所有性能问题的通用方法。虽然我不知道 C++ 和 Rust 的大规模性能基准,但不难列出一些 Rust 不如 C++ 的性能问题。
最大的一个可能,是 Rust 的移动语义是基于值的(机器代码级别的 memcpy)。相比之下,C++ 语义使用特殊引用(机器代码级别的指针),可以在其中处理数据。
理论上,编译器应该能够看穿复制链,但实际上却常常做不到。要知道, 一个相关的问题是不放置新的——Rust 有时需要从堆栈复制字节,而 C++ 可以就地构造东西对象。
有趣的是,为了使其尽可能高效而不稳定,Rust 的默认 ABI 有时比 C 更糟糕。
8、不安全(Unsafe)的定义
(1)可解释(非不安全(non-unsafe)的代码不会导致未定义的行为) (2)@模块化(可以单独检查不同的不安全块)
其次,据业内开发者的观察结果是,unsafe 实际上并不是模块化的。足够强大的不安全块实际上可以扩展语言。两个这样的扩展,单独使用时可能没问题,但如果一起使用,可能会导致未定义的行为、观察到的等效性和不安全的代码。