开发者撰文解释为何在系统编程中选择 Zig 而非 Rust
来源标题:Why Zig over Rust for Systems Programming
一位开发者撰文说明,自己在系统编程中更倾向用 Zig 而非 Rust,原因是 Zig 更贴近他思考机器实际运行方式。他承认 Rust 的借用检查器能防止大量内存安全缺陷,生态也更成熟,但认为 Rust 附带的约束较多。他强调这不是判定语言优劣,而是个人工作方式的选择。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
这篇文章并不是要宣称某种语言在客观上更优越。它只是个人的一些思考,谈谈为什么 Zig 与我的思维方式和工作方式更契合,而 Rust——尽管有很多优点——却并不适合我。
很多讨论把 Zig 和 Rust 之间的选择框定为一场纯粹的安全性辩论:Rust 在编译期强制保证内存安全;Zig 不这样做。这个差异真实存在而且很重要。但对我来说,它从来都不是核心问题。
我的问题更简单:哪种语言能让我清晰地思考机器实际在做什么,并且在我的意图和最终代码之间,尽可能少地横亘着繁文缛节?
在两种语言上都投入了大量时间之后,我的答案是 Zig。
Rust 的所有权和借用系统是杰出的工程。借用检查器能防止整类 bug,而在 C 或 C++ 中,诊断这类 bug 可能要花上数小时甚至数天。它的生态成熟,社区庞大而活跃;对于即使在对抗性条件下也必须保持正确的项目——比如浏览器引擎、密码学库或操作系统内核——Rust 是强有力的竞争者。
我并不是在否定 Rust。我只是选择不把它用于日常工作。
借用检查器会带来认知负担,而且这种成本并非恒定不变。它恰恰会在系统程序员最常打交道的领域里不断累积:传递裸指针、管理自定义分配器和 arena,以及构建所有权模式无法整齐套入严格树形结构的数据结构。
我一次又一次地发现自己为了已经理解的问题跟编译器较劲。我知道内存布局长什么样。我知道这些生命周期在实践中是正确的。然而,说服借用检查器变成了另一个独立的问题,与我所要解决的实际系统难题毫不相干。
Rust 的复杂度也显著增长了。trait、生命周期、闭包、async/await 以及强大的宏,每一个都增强了表达力——但它们也增加了阅读和维护他人代码时的脑力负担。这门语言的表面积还在不断扩张。
Zig 是一门小语言。它并不简单化——comptime、分配器模型和显式错误处理都有真正的深度——但它足够小,即使是在调试到凌晨两点的时候,我也能把大部分内容装进脑子里。
“分配器作为参数”的模式从根本上改变了我对内存的推理方式。每一个会分配内存的函数都显式接收一个 Allocator。没有隐藏的全局状态,也没有运行时的意外。你确切知道内存从哪里来、必须还到哪里去。这不是类型系统强制的安全;这是纪律强制的清晰——而纪律是我可以可靠推理的东西。
comptime 是另一个突出特性。它通过在编译期运行真正的 Zig 代码,让元编程变得显式且完全可追踪。没有隐藏的魔法,也就意味着没有意外的行为。
Zig 的错误处理坦诚得令人耳目一新。函数返回错误联合。你用 try 或 switch 处理它们,编译器会强制进行穷尽检查。没有异常,没有栈展开,也没有隐藏的控制流。失败路径就紧挨着成功路径出现在源代码里,它本就该在那里。
Zig 不会像 Rust 那样保护你免于自己伤害自己。你仍然可能写出 use-after-free 的 bug 或缓冲区溢出。编译器不会阻止你。
Zig 提供的是彻底的透明。当 bug 出现时,心智模型能干净地映射到硬件上,源代码与根因之间的距离很短。定位和修复问题变得直截了当。
对于我所做的这类系统编程——UNIX 工具、网络服务器,以及需要保持可读性和教学性的示例——这种取舍感觉恰到好处。
Zig 仍处于 1.0 之前,并且在快速演进。标准库在不同版本之间会有变化,这种不稳定性对生产工作来说有实实在在的成本。任何为关键系统选择 Zig 的人都应该仔细评估这一风险。
我是在睁大眼睛的情况下做出选择的。这门语言的核心设计连贯而深思熟虑。团队已经展现出纪律性,宁愿现在做破坏性变更,也不把技术债背到未来。随着 Zig 0.16.0 最近发布、1.0 已在视野之内,基础感觉是扎实的,方向也是对的。
Rust 是一门为严肃问题而构建的严肃语言,我深深尊重它。我只是不想每天都用它。
Zig 契合我偏好的系统编程思考方式:显式、对底层机器坦诚,并且小到可以完全理解。对我来说,这种清晰和透明比借用检查器强制的编译期保证更重要。
最好的工具是那个不挡你路、让你专注于问题的工具。对我来说,那个工具就是 Zig。
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。