C++ 和 Rust 是两种用于制作软件和硬件平台的系统编程语言。它们都能够与微控制器上的操作系统或固件等低级组件进行交互,或在应用开发的较高水平上进行交互。
本博客的读者可能最熟悉 C++,因此就不需要介绍了。然而,Rust 值得更深入了解。根据 StackOverflow 调查,过去五年里,Rust 已经成为最受喜爱的编程语言。的确,Rust 是目前的热门话题!
为什么要将 C++ 与 Rust 进行比较?
是否有必要将 C++ 与 Rust 进行比较?Rust 是否意欲替代 C++,或者它仅仅是让低级编程更易使用的工具?随着生态系统和社区不断发展,为了提高代码安全性,确实有必要将 Rust 与 C++ 进行比较。
其中一个明显的问题是,哪种编程语言对企业更有利?考虑到企业级软件需要在多个方面都有良好的表现,包括业内对方案的接受和支持程度,回答这个问题并不容易。
为什么是 Rust?
Rust 常被视为 C++ 的竞争语言,在编译时提供内存安全功能。与 Java 或 Go 等其它编程语言不同,Rust 无需使用垃圾收集器,确保了运行时间的确定性、实现低延时和高通量,这一点和 C++ 类似。长期以来,C++ 中手动内存管理存在的问题都是 C++ 开发人员面临的最大挑战之一,但只要汇编码和硬件的连接更加紧密,C++ 的速度就会快得多。Rust 可以实现类似的低级别操作和高性能,同时具有安全模式,有助于在编译时就消除内存漏洞,以免在运行使用中出错。
Rust 不仅有助于防止内存分段故障或泄露,而且在不同线程同时访问同一内存时,利用了相同的编译时间保护来避免数据竞争,使并行变得更容易。
但是,如果 Rust 这么好,为什么并未出现大量 C++ 转移到 Rust 的情况?是否存在捕捉机制?这是一个非常有争议性的话题。C++ 爱好者和 Rust 粉丝之间关于“哪种编程语言更好”的讨论最终可能会以互殴收尾。当然,这种讨论并不能得出正确答案。了解各种编程语言的差异及其受欢迎的原因,有助于纵观全局,并做出明智的决定。
Rust 增势强劲(但毫无疑问仍落后于 C++)
虽然 Rust 未广泛使用,但 Rust 基金会已经成立,还有几家大型公司已经与其建立了不同程度的合作关系。例如,Facebook 已经加入了 Rust 基金会,将 Rust 用于其开发的各个方面,并承诺发展 Rust 生态系统;Google 目前也支持使用 Rust 构建安卓操作系统 – 理由是 Rust 提供了获取低级系统资源的能力,同时内存安全保障优于 C++。Rust 的其他拥趸者还包括 Mozilla、AWS 和 Cloudflare。
大多数使用 C++ 但正考虑 Rust 的企业并不愿意放弃他们的 C++ 代码库,反而是探索哪些领域使用 Rust 会更好。例如,在微软等大公司内,就可以看到这两种编程语言背后不同力量的博弈。据微软公司的 Rylan Levick 所述,由于内存安全问题,微软正逐步从 C++ 转向 Rust,并且认为 C++ 不够安全,不能用于开发关键任务的基础设施。同时,微软的首席软件开发工程师 Gabriel Dos Reis 在 cppcast 播客中表示,微软目前和未来仍将以 C++ 为中心,微软正在开展 Rust 实验,但据其所知,目前还没有使用 Rust 构建产品。你可以前往微软的关于 Rust 与 Go 的选择及其与 Rust 的实验了解更多信息。
Linux 创始人 Linus Torvalds 也表达过与 C++ 和 Rust 相关的观点。关注 Linus 的人都知道他是一个彻彻底底的 C 语言追随者,不喜欢 C++。Linux kernel 就是采用的纯粹 C 语言构建(搭配一些内联汇编组件)。在今年早期的采访中,Linus 表示已经采取行动,评估是否可以使用 Rust 作为开发 Linux kernel 的支持性语言。至于 C++,Linus 认为它是一种“垃圾语言”,根本不能解决 C 语言的任何问题。当然,这在 Slashdot 上引发了大量讨论。更多关于 Linus 对 Rust 的看法,还可以在 ZDNet 对他的采访中找到。
C++ 仍然是王者
不可否认 Rust 非常受欢迎,极具吸引力,但 C++ 仍然占据主导地位。在 2021 年 8 月的 TIOBE 指数中,C 语言仍排在首位,而 C++ 在第 4 位。根据最近的指数,Rust 已经从第 27 位升至第 24 位。当然这是显著飞跃,但相比于 C++,Rust 仍然望尘莫及。
回顾 C++ 的起源及其越来越受欢迎的历程,我们记得许多开发人员从原先的 C 语言转向 C++,主要就是因为 C++ 能够实现面向对象的功能,与 C 语言的方案相比,C++ 具有利用模板实现通用编程以及丰富标准库容器等优势。
目前还不能得出合理观点的另一原因是:C++ 具有无与伦比的支持基础。C++ 生态系统庞大,而此时的 Rust 尚且年轻,在这方面尚且不足。例如,对游戏编程感兴趣的 Rust 开发人员可以在关于游戏开发中找到有趣的资源。然而,目前还没有成熟度足以比拟 C++ Unreal Engine 5 的产品。简单地说,如果你正在尝试解决 C++ 中的问题,那么在你之前肯定有很多人也这样做过,所以你很可能会找到相关的库。但现在,Rust 没有这样的库。
诚然,Rust 用得越多,应用的范围就越广,也会产生新的库和框架,进而提高 Rust 的普及度。但同时,随着时间推移,用户的增加也会带来新的需求、新的特征和新的变化,使这种语言变得更加复杂。Rust 已经具有声明过时的语法选项。
在受欢迎度排名中,Rust 远落后于 C++。
来源:https://www.tiobe.com/tiobe-index
比较
与往常一样,大部分比较的答案都是“看情况”,因为根据问题和实施,情况各不相同。但是,我们试图从这两种语言中逐项找到某些趋势。
C++ 和 Rust 编译器和平台支持
Windows 32 位和 64 位架构、Mac 和 Linux 等多种平台均支持 C++ 和 Rust。当然,相比 Rust,C++ 拥有的编译器更多。但是,由于 Rust 编译器基于 LLVM,因此在 LLVM 支持的各种环境中均支持 Rust 编译器,包括实时 VxWorks 环境中的 Rust 支持。Rust 项目定义了三级目标支持,其中第一级为 Rust 项目自身保证完全认证。C++ 标准委员会不保证此类支持,不过这并不会影响编译器认证或设置编译器测试台。C++ 编译器供应商往往在遵守 C++ 标准方面做得很好,但你可能会发现一些小瑕疵,尤其是在实现编程语言新特性时。由于 C++ 使用广泛,编译器实现过程中的瑕疵往往会在报告后迅速修复,特别是当它们可能起着至关重要作用时。
我的建议很简单:虽然大多数环境都支持 Rust,但是如果你的环境不支持,请不要使用它。
学习曲线和开发速度
对大多数 Rust 新手来说,不论他们是其它语言的初级程序员还是资深人士,Rust 语法和方法、所有权机制、Rust 实现 OOP 的方式等,都相当复杂。Rust 的使用没什么不同,因为一开始,开发人员也要学习语法。
C++ 也不简单。然而,大多数从 C、Java 或 C# 转向 C++ 的开发人员都觉得 C++ 的基本语言更容易理解。
尽管如此,Rust 程序员认为,在他们学习掌握语法之后,Rust 的内存管理和所有权机制可以促进加快开发,消除编译错误导致的问题,避免变成运行问题。另一方面,C++ 程序员认为赋予程序员这种能力(即编译错误)是好事,这样你可以表达自我,而不受语言限制,程序员也肩负更多责任。此外,C++ 程序员认为,C++ 所有权模型提供了 unique_ptr 和 shared_ptr,同时赋予程序员更多的力量。相比语言内支持和所有权的执行,Rust 程序员将 C++ 智能指针视为一种糟糕的基于库的解决方案。这又回到了严格执行的问题,相比非强制性语言选项,严格执行的学习曲线可能更为陡峭。
表现
用二者之中的任何一种语言,编写出的应用程序都能在时延和通量方面具有良好的表现,因为他们都属于低级程序,更贴近硬件运行。这两种语言都不依赖垃圾收集器,这样不仅提高了性能,还增强了运行速度的可预测性。例如,由于内存问题和垃圾收集导致的时延激增,Discord 将他们的一种业务从 Go 迁移至 Rust。
每种语言都有其竞争基准,关于哪种基准表现更好的讨论也很多。深入研究基准的人都知道,这些基准可能存在争议。但是结果往往相互矛盾,意味着这两种语言竞争激烈,都有良好表现。
你可以点击这里和这里了解基准示例,点击这里查看基准总结。博客文章中关于 C++ 与 Rust 比较的分析也值得一读,它打破了某些神话,深入探讨了这两种语言之间的表现差异问题。
值得指出地是,当 Rust 代码中需要进行某些特定优化时,所有权模型会被破坏,专家级开发人员如果相信自己的代码 100% 无错误,可以采用 Rust 不安全模式。在这种模式下,内存安全网处于切断状态。这在某些情况下是必要的,因为基于统计代码分析的 Rust 编译器会更保守;而在实践中,有时无法实现最高级别的优化。从某种程度上,Rust 和 C++ 将内存管理的复杂性分成两个不同的方向:C++ 无约束,但你可以使用智能指针等安全控件;Rust 的语法约束力更强,但你可以选择“不安全”模式(在某些罕见情况下,如性能要求或存在其他需求时)。采用这两种语言都可以编写出具有高性能的代码,因此很难判断一般情况下哪种语言的表现更好。真正的答案就是:根据实际代码而定。
内存安全
C++ 在目前常用的智能指针方面取得了明显进步,但你可能也看到报道说谷歌发现 chrome 中 70% 的严重安全漏铜都与内存安全问题有关,在这方面 C++ 相当落后了。与之相反的是,人们愿意使用 Rust 的动机就是内存安全。实质上,为了避免在内存安全与速度之间进行权衡,C++ 把内存安全问题留给了开发人员,而 Rust 却设定了固有的内存安全边界,不过也可以采用“不安全”模式。如果你认为 C++ 中内存安全正是问题所在,那么选择 Rust 更好。似乎很多 C++ 开发人员都认为目前 C++ 中的内存安全并非大问题,或者即便存在问题,也不足以让 C++ 爱好者转而选择繁琐的 Rust 语法,这并非毫无逻辑可言。
指针和地址
Rust 和 C++ 语言都广泛支持指针,在两种语言中,首选都是智能指针。使用原始指针时,C++ 开发人员主要依靠手动代码审查和静态代码分析工具检查错误,原始指针不能在不安全块外使用。不安全块的确是手动审查的主体,虽然还有一些辅助工具。
OOP
尽管 OPP 很受欢迎和依赖,但 Rust 并非理所当然地完全支持它。你不能继承 Rust 中的结构体,但你可以实现特性。通过特性和 dyn 的实现,你可以在 Rust 中做到多态性。其中 dyn 用于整个特性,并影响实现该特性的接收对象的所有函数调用,使其具有动态性。Rust 程序员认为这就是多态性的正确模式,而数据继承实际上并不需要,因为你可以依靠组合来重复利用其它类型。事实上,Rust 允许使用多态性的方式需要明确,组合 (“has a”) 和类型接口 (“is a”) 之间也有明显的差异。C++ 程序员可能会说,Rust OOP 模型简单纯粹,这一理由的确很有说服力,但除非 Rust 代码使用派生宏模拟继承,否则他们仍然不会选择 Rust。总之,Rust 和 C++ 是两种不同的编程语言。萝卜青菜各有所爱,这只是口味不同而已。需要注意的是,C++ 和 Rust 都有很多追崇的程序员(热爱其中一种的很大概率会极为厌恶另一种),所以你不能说二者之中的任何一个不好。
并发性
C++ 中并发快速稳健,很多库可用于 C++ 多线程,包括 C++ 标准库和 Boost 库。然而,在线程安全方面,Rust 的内存安全特性有助于防止数据竞争等并发问题。数据竞争可以说是最糟糕的并发漏洞类型:它容易出现,又难以定位。不过,Rust 会让你更难共享数据,同时确保不会形成数据竞争。对自己代码有信心的 C++ 程序员,可能会认为 Rust 在实现多线程应用时过于束缚。Rust 程序员则会驳斥“刚愎自用最为可怕”:Rust 的安全检查最适合这些自信过头的程序员,即便这导致他们不得不改变在线程之间分享数据的方式。
社区支持
这两种语言都通过严格管控的过程演化,C++ 通过 C++ ISO 委员会,而 Rust 通过 Rust 基金会。两种语言的社区都很活跃。然而,与 C++ 相比,Rust 尚很年轻,所以群众基础要弱一些。C++ 有很多论坛、开源项目和 StackOverflow 贡献者。事实上,C++ 已经存在很长一段时间,某个开发人员遇到的问题几乎都有人遇到过。
让我们以两个相似开源为例(一个采用 C++,一个采用 Rust)来说明这两种语言社区支持的区别。Beam 是用 C++ 编写的开源项目,执行 Mimblewimble 区块链协议。Grin 是采用 Rust 编写的同类项目,执行的也是同一种协议。两个项目同时于 2019 年初上线。尽管由不同的群体创建,但它们的开源属性意味着,它们的演变和进步依赖社区的支持。但如图所示,C++ 项目(即 Beam)获得的支持远远超过 Rust 项目(Grin)。
以下为去年 Rust 语言编写的 Grin 的活动情况。
来源:https://github.com/mimblewimble/grin/graphs/commit-activity
以下为去年 C++ 语言编写的 Beam 的活动情况。
来源:https://github.com/BeamMW/beam/graphs/commit-activity
外部库
C++ 和 Rust 都有大量的框架和库可以使用。尽管二者存在较大时间差距,但 Rust 已经拥有大量库可供选择,协助进行网页开发、游戏开发、操作系统开发、区块链等。当然,C++ 也拥有海量的库可供选择(点击此处了解 C++ 库排名)。两种语言都有大量积极活跃并给予诸多贡献的支持者,往往你使用其中任何一种语言,都能实现常用功能需求。
包管理和工具
开发人员喜欢 Rust 的另一个原因就是包管理。Cargo 是官方的 Rust 包管理器,与开发人员在 Python 或 JavaScript 中使用的不同。虽然 C++ 中也有许多很好的包管理器,例如 Conan,但开发人员表示,这些包管理器都没有 Cargo 好用。总的来说,对于像 Rust 这样年轻的编程语言,其工具集对 C++ 来说仍然效果惊人、极具竞争力。虽然 C++ 在为开发人员提供良好工具集方面有点滞后,但它最终已经在支持工具方面开始缩小差距。
哪种语言对企业更有利?
哪种语言对企业更有利?这取决于正在开发的内容,以及开发团队的经验。2020 年 Rust 调查得出了一些有趣的事实,包括 40% 的受访者在工作中使用了 Rust。再加上我们已经知道上述几家大型公司已经使用了 Rust,毫无疑问这不能忽视。尽管如此,受访者也有诸多抱怨,涉及的方面包括:学习曲线陡峭、需要更好的培训和文档(这有点令人惊讶,因为 Rust 其实有很多文档),以及完全过渡到 Rust 所需的时间和精力。
如果有更多程序员 使用 Rust,那么 Rust 在企业中的推广就会更加简单。对此,今年 Rust 用户的最大变化似乎就是学习和使用 Rust 的学生人数增加。如果这确实代表整个社会的趋势,那么未来预计会有更多的 Rust 程序员。同时,我们必须记住,与 Rust 相比,目前有更多的 C++ 代码行需要维护,同时也有更多的 C++ 程序员产生。
结论
C++ 和 Rust 都是具有良好用户基础和社区支持的系统编程语言。它们各有优缺点,因此二者很有可能会对峙很长一段时间。那么问题随之而来:C++ 是否会继续占据统治地位,而 Rust 仅占小份额?还是 C++ 会被 Rust 占领相当大的市场份额?
现在就得出最终结论,可能还为时尚早。2020 年 Rust 调查列出了过去一年 Rust 语言中有所改善并受到欢迎的几个领域。然而,随着 C++20 的发布上市以及 C++23 的开发,毫无疑问 C++ 不会淘汰。至少现在不会。
企业是否应准备好迎接 Rust?当然,有很多项目都可以从中受益。是否考虑在 C++ 上使用 Rust?现在还不太可能。在这场竞争中,两种语言都会不断改进,如果二者之间能够实现更好的互操作性,那么未来可能建立相当长的合作与尊重的关系。
点击获取 Incredibuild 的 C++ 编译加速试用 License!
更多信息
Rust 和 C++ 之间的详细比较,重点关注语法差异:
https://www.apriorit.com/dev-blog/520-rust-vs-c-comparison
Reddit 上关于 Rust 与 C++ 比较的讨论:
https://www.reddit.com/r/cpp/comments/611811/have_you_used_rust_do_you_prefer_it_over_modern_c
ycombinator 中的类似讨论:
https://news.ycombinator.com/item?id=24037045
使用 Rust 和 C++ 的行业:
https://www.efinancialcareers.co.uk/news/2020/09/rust-vs-c-hedge-fund-jobs
使用 Rust 的公司:
https://serokell.io/blog/rust-companies