我知道这篇文章发出来必然会被许多Rust爱好者批评,但是我想发表一下我的观点,也欢迎各位老友来评价导语Rust 自诞生以来便被视为"新时代系统编程的圣杯",不少拥趸(有时被戏称为"Rust邪教徒")将其宣传为一门能"下写小脚本、上写操作系统",同时性能媲美C++,安全性碾压Java的全能型语言。然而,技术世界从不欢迎乌托邦,Rust的设计理念与生态系统在工业实战中的实际表现远未达到其理想主义设定。 本文从六个角度(全能语言?安全可靠? 构建与信任链, 异常系统和Panic, 真实业务场景下性能,就业岗位?),以历史数据与现实工程痛点为基础,揭示Rust完美主义背后的代价
一、全能语言?:上能写内核、下能跑脚本?不可能!
Rust支持从底层裸金属嵌入式开发(如Rust for Linux)到高层Web服务,但问题是:这根本不等于它"擅长"所有。 历史上,没人能真正做到"一门语言写天下":
C++写底层优秀,但开发效率低、构建困难。
Python写脚本飞快,但内存与性能不足。
Java是后端巨擘,但从不染指内核。
Go效率高、生态好,但嵌入式和游戏基本不见踪影。
对于个人这样的上能写内核,下能跑脚本的语言确实有很大的吸引力,但是如果你真的追求完美(我知道有许多完美主义者喜爱Rust),不妨把所有语言最强大的地方结合起来,而非学习一个写什么都不是最好的语言。这严格意义上来说并不完美。
Rust虽尝试横跨全栈,但其写脚本不如Python、Web不如Go、工程规模不如Java、底层普及度不如C/C++。结果是:既没有统一社区语境,也缺乏行业范式共识。这不是强大,而是一个四不像。
二、安全≠可靠:Rust能避免内存问题,却防不住业务逻辑漏洞
Rust最大卖点是内存安全。这点的确成立:其所有权模型、借用检查器能有效阻止空指针、悬垂引用、UAF等经典漏洞。
但现实是:
绝大多数线上故障并非内存错误,而是业务逻辑漏洞。
Google SRE团队在《Site Reliability Engineering》中指出,大量事故源于配置错误、依赖不稳、数据不一致、边界处理失误。 现实案例包括(不再一一举例,这样的例子有许多了,一般都是由于配置失误/数据结构变动/逻辑错误而引发的,并非资源竞争/内存泄漏问题):
2021 年 Facebook(现 Meta)全球宕机,原因是配置更新错误并非内存问题。2021 Facebook outage - Wikipedia.
Rust对这类问题无能为力。它可以防止你用错内存,但无法阻止你用错逻辑。
三、构建地狱与黑箱依赖:Cargo的工程代价令人崩溃
许多Rust爱好者认为他们的构建系统非常先进,但是它小项目中尚可使用,但在中大型工程中暴露出严重问题,尤其对企业级应用/大型项目极不友好。
依赖爆炸:一个简单的 HTTP 服务可能会拉下超过 300 个 crates,很多是功能极度碎片化的小包。这种"npm化"的生态带来了维护地狱:
很多 crates 半年无人维护(如
chrono
,长期 PR 堆积)。更新频繁但版本跳跃大,经常破坏兼容性,这也是一个阻碍Rust成为企业级/大型项目语言的因素之一,没有LTS版本,官方支持不足。
构建不可控:
一行代码变动可能触发整个 crate graph 重编,构建缓存脆弱。
CI/CD 编译时间动辄 30 分钟,严重影响开发节奏。这在企业级开发中是非常致命的,意味着CI/CD成本,时间成本的增加
缺乏"构建剖析工具"(如 Gradle Build Scan 或 Bazel Profile)来定位瓶颈。
黑箱风险大(信任链问题):
Cargo 下载包时可能附带
.rlib
、.so
或.wasm
等编译产物,难以完全审计。企业级安全审计难以接受这种不确定构建路径。
对比 Go: Go 的所有依赖均为源码构建,go mod vendor 可以完整锁定依赖状态。 主流库如 gin、pgx、minio 均由知名组织维护,更新节奏稳定。 构建时间快,跨平台打包简洁,产出为单一可执行文件。
对比 Java:Java 虽不能完全防止 JAR 包中夹带二进制,但主流构建物经过 Maven Central 或企业 Nexus 仓库,版本审计与发布控制严格。 构建生态成熟分层:Ant(轻量)、Maven(规范)、Gradle(可扩展、可组合)。支持构建缓存、增量构建、依赖剖析与缓存调优(如 Gradle Build Scan、Jenkins/GitLab Runner 缓存机制)。总结一下就是:
依赖极其碎片化:一个项目动辄 300+ crates,极其臃肿。
版本兼容性差:库更新随性,很多库半年无人维护,语义版本形同虚设。
构建缓存脆弱:稍有改动,整个依赖树重编,编译时间呈指数增长。
黑箱构建风险高:很多 crates 下载时附带预构建二进制,源码无法审计,违反了最小信任原则(特别对安全行业极为敏感)。
四、异常系统不完善,使用错误码代替具体错误,panic无法控制:线上崩溃不可预测
Rust没有传统的异常系统:
Result<T, E>
用于可预期错误panic!()
用于不可恢复错误(直接终止线程或进程) 问题在于:很多库内部直接 panic,调用者无法catch也无法处理
默认 panic=abort,不带堆栈信息
堆栈必须设置环境变量
RUST_BACKTRACE=1
才能看到,而且容器环境下很容易丢失 虽有panic = "unwind"
模式,但带来构建、性能和逻辑复杂度的大幅上升。 现实中,你根本无法保证某个依赖不会在奇怪的场景里 panic,而你也无法从容降级或做异常捕获处理。
五、业务场景下性能不如Go/Java/C++:Hello World是幻觉
Rust爱好者常引用各种"Hello World Benchmarks"吹嘘其性能接近C++,但一旦进入真实场景(如业务服务 + 数据库 + 存储访问),问题就来了:
实际 HTTP + SQL 场景下,Go性能普遍优于Rust。
原因包括:
Go有成熟的连接池与协程调度
Rust需要借助复杂的 async 生态(如 tokio + hyper + sqlx),工程繁琐
编译器优化依赖链冗长,难以调优
不少团队在实践中发现:
Rust性能优势仅在极端场景下成立,而在普通业务开发中,综合性能甚至不如 Java/Go。
以 S3、PostgreSQL 访问为例,Rust 框架的表现远落后于 Go 的 gin + pgx + minio
。
六、设想很美好,现实很骨感:
截止到写这篇文章的日期 2025年4月30日08时55分 UTC+8,数据来源领英: 中国: Java岗位共有:219,309个 C/C++岗位共有: 314,000+个 Go岗位共有 4,000+个 Rust岗位共有: 433个
美国: Java岗位共有: 297,000+个 C/C++岗位共有: 112,000+ 个 Go岗位共有: 368,000+个 Rust岗位共有: 5,000+个
结语:Rust是工具,不是宗教
Rust 是一门好语言,但它不是全能神。其所有优势(内存安全、零开销抽象)都伴随着巨大的工程代价(构建成本、异常机制缺失、生态不稳定)。
成熟工程从不迷信语言,而是选择适合团队、业务、项目生命周期的工具。
Rust可以用于性能敏感模块,但大规模工业实践仍然需要多语言协作。
盲目崇拜 Rust,只会让你陷入"技术理想主义"陷阱,而现实,往往是复杂的。
没有评论:
发表评论