Rust这四个问题,从新手到专家都在被折磨

3 阅读8分钟


「Rust 难学,但学会了就好了。」

这句话在 Rust 社区流传已久,几乎成了一种安慰新人的口头禅。但 Rust 官方 Vision Doc 工作组在对大量开发者进行系统访谈后,得出了一个更复杂的结论:

挑战不会因为你学会了 Rust 就消失,它们只是换了一张脸。

新手被借用检查器绊倒,资深开发者被 async 的复杂性困住,嵌入式开发者面对稀缺的 no-std 生态,安全关键系统团队担忧认证工具的空白。不同人群在不同阶段面对的是完全不同的墙。

这篇博客,是 Rust 团队罕见地把这些问题摆到台面上公开讨论的一次尝试。


编译速度:唯一一个折磨所有人的问题

访谈涵盖了从初学者到专家、从嵌入式到 Web 的所有群体。在所有挑战中,只有一个被每一个群体都提到了:

编译太慢。

"Java 大概 100 毫秒,Rust 视改动量从 5 秒到 1 分钟不等。" —— 大型公司后端系统资深工程师

"改一下 UI 里盒子的 padding,要等 10 秒以上的迭代周期……这是我们默默接受的痛苦。" —— GUI 开发团队

这不只是「等待几秒」的问题,博客用「开发速度税」来形容它:每一次改动都要缴这笔税,时间长了会严重打击迭代意愿。对于 GUI 开发者来说,视觉反馈本来就需要高频迭代,10 秒的等待足以让思路断掉;对于安全关键系统团队来说,有人提到一次完整构建需要 25~30 分钟,「等半小时才知道自己写错了」是真实存在的工作流。

好消息是,社区已经有一些值得关注的尝试:

  • subsecond:Dioxus 团队开发的热重载 crate,目标是让 GUI 开发不再需要每次都全量编译;

  • Wild linker:面向 Linux 的高速链接器,计划支持增量链接。

官方的建议是,应当把编译性能作为语言层面的一等公民来对待,而不是一个可以等待的「实现细节」。


借用检查器:先苦后甜,但苦的时间因人而异

借用检查器是 Rust 最具辨识度的设计,也是新手遇到的第一道坎。

"第一次读那一章的时候,我真的觉得,这是什么东西?" —— 把 Rust 作为第一门编程语言学习的开发者

"我真正理解借用检查器,是在花了大量时间写 Rust 之后。" —— 某开发者工具公司高管

访谈数据支持了一个有些「残忍」的事实:借用检查器的学习曲线确实主要影响新手,资深 Rust 开发者基本不再把它当作痛点。但「资深」的门槛并不低,即使是已经能流畅写 Rust 的开发者,偶尔还是会被借用检查器卡住。

这里面还有一个背景差异:有 C/C++ 经验的开发者需要「忘掉」一些指针相关的直觉;而从高级语言(Python、TypeScript)转来的开发者则需要从零建立对底层内存模型的认知,两条路的难点完全不同。


async:Rust 的另一道深坑

如果说借用检查器的问题会随时间消退,那 async 是一个完全不同性质的挑战——它是一个持续影响有经验开发者的问题。

"我对 Rust 最大的抱怨就是 async。如果要用某个工具,就被迫进入那个模型……不只是换了一门语言,而是换了一种编程模型……我完全没有经验,我一直在回避它。" —— 在大型公司做安全 agent 的开发者

"当 Rust 同时用了 async、泛型和生命周期,那些类型就变得极其复杂,你基本上得是某种 Rust 神。" —— 有生产 Rust 经验的软件工程师

"总体印象其实相当负面。感觉没做完……需要大量晦涩的知识。" —— 研究软件工程师

博客把 async 的问题概括为三个层面,并戏称其为「三骑士」:

语言层面的不完整感。 async 在某些语言特性上落后于同步 Rust,例如在 dyn trait 中使用 async 函数,至今仍未稳定。

生态碎片化。 生态中存在多个异步运行时,tokio 是事实标准,但并非唯一选择。一旦依赖了某个库,往往就隐性绑定了它的运行时,这种锁定会影响整个项目的架构决策。

"还是有很多情况,你找到一个看起来有用的库,然后发现它立刻把你锁进了 tokio 或其他某个运行时。" —— 社区开发者

文档与学习资料的缺位。 《Rust 程序设计语言》这本官方书主要聚焦于同步代码,async 的系统性教程至今稀缺,形成了博客所说的「悲伤鸿沟」——基础 Rust 和 async 编程之间存在巨大的学习断层,需要投入大量精力才能跨越。


生态导航:选择困难与默会知识

Rust 的 crates.io 上有大量库,但这反而成了一个问题。

"人们不用 Rust 的最大原因,是他们进入的生态圈和预期不符。既没有 C++ 那样的工具链,也没有相应的库。" —— 大型科技公司开发者

"crates 基本上是不可被发现的……你用哪些 crate 来做具体的事,这是一种通过经验积累的默会知识。" —— Web 开发者

问题不是库不够多,而是选对库需要一种新手并不具备的专业判断力。哪个 crate 在生产环境经过验证?哪个已经停止维护?哪两个 crate 在运行时会冲突?这些知识散落在社区讨论里,没有系统性的入口。

Rust 团队坦承,这个局面有一部分是官方有意为之的结果:为了不扼杀创新,官方刻意不对特定 crate 给予背书,但这个取舍是否仍然合适,团队认为值得重新评估。


不同领域各有各的难题

除了上述普遍问题,不同使用场景还叠加了专属挑战:

嵌入式开发者 面临资源双重约束:debug 构建体积往往超出小型控制器的存储上限,被迫使用优化构建,而优化构建又让调试变得困难;no-std 生态虽然在成长,但缺口依然显著。

安全关键系统团队 需要 Rust 的内存安全保证,却苦于缺乏与 C++ 同等成熟度的认证工具链。加之 Rust 版本迭代快,与安全关键领域对稳定性的严苛要求之间存在天然张力,即便技术优势明显,管理层的信任也难以快速建立。

GUI 开发团队 将编译速度的痛苦放大到极致——视觉调整本来就需要高频反馈,等待 10 秒才能看到一个 padding 改动的效果,是对开发体验的持续消耗。


官方给出的四条建议

基于访谈数据,Rust 官方工作组提出了以下方向:

一、将编译性能作为一等公民

增量编译改进、构建系统创新、减少迭代周期——这是覆盖所有用户群体的最高优先级改进方向。

二、加强生态引导与跨 crate 兼容性

帮助用户找到适合的 crate,同时推动生态中更好的兼容性,减少因库选择导致的架构锁定。

三、针对不同背景提供差异化学习路径

来自 C++ 的开发者和来自 Python 的开发者,需要的不是同一份教程。直接对比「引用 vs 指针」、提供领域专属的学习材料(如《嵌入式 Rust 指南》已经做到了),比通用教程更有效。

四、弥合 sync 与 async 之间的鸿沟

短期内可稳定 dyn trait 中的 async 函数等已久等的特性,改善编译器对 async + 生命周期问题的错误提示;中期可将基础 async 特征和函数纳入标准库,从根本上改善生态碎片化。


一句话的底色

博客最后引用了一位工程师的话,某种程度上也代表了大多数 Rust 用户的心态:

"如果这些问题都解决了,我会是一个快乐的 Rust 程序员。如果没有,我还是会是一个 Rust 程序员。"

挑战存在,但 Rust 解决的问题是真实的,这是它至今仍被广泛需要的原因。承认挑战,是改进的起点。


参考资料: