楼主观察到的这个现象确实很有意思,Bun从Zig转向Rust,表面上看像是开源界又一个“重写狂魔”的故事,但细究技术决策背后,其实能读出一些对系统软件工程本质的思考。
从语言设计哲学上看,Zig和Rust正好站在两个极端。Zig追求的是“无隐式控制流、无隐式分配、无预处理器、无宏”的简洁性,它把内存管理的最终责任完全交给程序员,只是提供了比C更好的工具(比如defer、编译期求值)。这种思路在小型到中型项目里非常高效,你可以精确知道每一行代码在做什么,没有隐藏的成本。但问题在于,当项目规模膨胀到Bun这种程度——一个需要同时处理HTTP服务器、包管理器、打包器、Native模块加载的庞然大物——显式管理的认知负载会指数级上升。团队在某个时刻一定会发现,他们花在追踪use-after-free和data race上的时间,已经超过了实现业务逻辑的时间。
Rust走了另一条路:通过所有权和生命周期,把内存安全规则编码进类型系统,让编译器在编译期就排除掉那一整类bug。这当然有代价,就是楼主说的borrow checker把脑袋check大。但换个角度看,borrow checker其实是在帮你做一件你在Zig里需要自己做的事——维护一个精确的心智模型,记录每一块内存的引用关系。区别只是,编译器用形式化规则强制你写清楚,而不是靠code review和valgrind去事后补救。对于Bun这种长期维护、多人协作的项目,这种强制性能显著降低技术债务的积累速度。
有一个具体的例子值得参考:2022年,Cloudflare的Pingora项目用Rust重写了Nginx C模块,他们在博客里详细对比过,Rust版本在同等负载下不仅没有segfault,而且因为编译器能做出更激进的优化(得益于aliasing信息的明确性),延迟反而更低。这某种程度上也解释了为什么Bun团队愿意承受迁移的阵痛——他们赌的是长期的维护效率和性能天花板。
至于值不值得继续磕Rust,如果只是写写个人项目或者脚本,borrow checker的投入产出比确实存疑。但如果你未来想做系统软件、数据库、网络中间件这类对正确性和性能同时有苛刻要求的领域,Rust目前几乎是唯一的选择。那种“编译通过就几乎不会崩”的体验,会在项目上线后持续回报。楼主说编译成功比鱼上钩还爽,其实再往后走,你还会体验到另一个层次:重构时随心所欲地改架构,编译器帮你揪出所有遗漏的引用,改完跑一遍测试直接上线,那种安全感是GC语言和手动管理语言都给不了的。
不过学习方法上,建议不要一上来就和borrow checker死磕。可以先多用用Arc、clone这种“逃课”手段,把程序跑起来再说。等你能直观感受到数据流向了,再逐步优化掉不必要的堆分配,这个过程会自然很多。Rust社区有个说法叫“先写对,再写快”,挺适合上手阶段。另外,多看看标准库里的Iterator和组合子设计,对理解函数式风格下的所有权转移很有帮助。
嗯钓鱼带笔记本这种状态,其实很适合消化Rust的概念。很多抽象需要一段放空的时间才能内化,我当年学Haskell的monad就是钓鱼时想通的(虽然那次一条没钓上来)。