17611538698
webmaster@21cto.com

我回到了Zig

图片

21CTO导读:本文作者讲述了自己从 Zig 跑到了 Rust,再回到 Zig的心路过程。

Zig 的受欢迎程度正在上升。虽然它尚未占领 Rust 或 Go 那样大的开发者市场,更不用说 C 语言了,但它已被一些大型项目和无数的小型项目采用。因此,它正成为未来一门重要的编程语言。

我对 Zig 感兴趣已经有数年,所以我决定重新审视一下这门语言,看看我现在对它的看法如何。

我为什么喜欢Zig


我第一次接触 Zig 是在 2020 年,当时一位编程导师向我介绍了它。他和同事们对这门新兴语言充满着热情,因为它支持编译时代码执行,并且拥有优美而简洁的抽象形式。

于是,我也决定亲自体验一下。

当时,我还在学习C语言。我享受着对电脑的掌控,但C语言过时的抽象概念和糟糕的工具让我感到沮丧。Zig虽然是新语言,还不稳定,但它承诺可以“取代”C语言,这深深吸引了我。既然可以学习下一代编程语言,为什么还要学习C语言呢?

我观看了作者 Andrew Kelley 不少的演讲。其中有一个《软件应该完美》对我影响甚大,可以说它塑造了我对编程语言乃至整个软件应有样貌的看法。在那次演讲中,Andrew 强调了显式内存分配、无隐藏控制流以及通用可重用性的重要性。这些也成为了我之后在任何编程语言中寻找的价值所在。

因此我转而使用 Zig。我编写了一些玩具编程语言,尝试了文学编程工具,还玩转了 Web 服务器。

我很喜欢使用 Zig。它比 C 语言更友好,而且没有 C 语言的那些致命缺陷。

转学Rust


然而,Zig总是破坏我的代码,我还厌倦了这种频繁的更新。

当时我还是个学生,没多少时间更新代码以兼容最新版本的语言。那时还没有anyzig,无法轻松地在同一系统上处理多个Zig版本。我经常几个月都无法继续做某个项目。等我重新开始的时候,却不得不进行大量的重构,而我根本不懂这些重构是如何让代码再次运行的。

Zig 生态系统当时并不成熟。作为一名新手程序员,我没有足够的技能独立完成所有工作。可用的库很少,可供学习的示例也寥寥无几。标准库一直在变化。每次我以为自己理解了它的抽象原理,它又会发生变化。默认文档不稳定也加剧了这个问题。

于是我转而学习 Rust。那时 Rust 已经稳定运行多年,并且拥有强大的生态系统。但学习 Rust 的过程很痛苦,我好几次都想放弃——但一旦掌握了,它就非常实用。这对我来说至关重要。Rust 是一种快速、底层的编程语言,它拥有我所需的表达能力,而且没有不稳定的缺点。它还迫使我建立了一种记忆模型,这种模型对于内置检查较少的语言也同样适用。

好处在于,由于代码不会崩溃,我能够编写可重用的代码,而无需隐藏控制流或垃圾回收器。虽然它隐藏了内存分配,使使用 C 语言变得困难,但它几乎让我完全理解了 Zig 吸引我的原因。

我热爱 Rust,至今仍然乐于使用它。它的抽象特性给我带来了极大的乐趣。然而,我对该项目的一些发展方向感到担忧。

我为何又回归


Rust 仍然不够完美。虽然它提供了我所期待的许多编程语言特性,但它并非创建我想要的可复用程序的最佳选择。FFI 比较难用,交叉编译令人恼火。隐藏的、不可避免地存在内存分配问题也让我感到困扰。由于受限于 LLVM,它要像 C 语言那样支持如此多的平台,恐怕还需要很长时间,甚至永远也做不到。

此外,它的管理方式仍然让我感到不满。它有几个大型企业基金会成员,这几乎肯定会影响 Rust 的开发方式。当世界上最大的公司每年都给你几十万美元时,你肯定不想得罪他们。

尽管如此,我原本愿意接受这些,直到“氛围编码”(vibecoding)的祸害席卷开源社区。令我震惊的是,许多软件项目竟然接受了LLM生成的代码。我一直以为LLM在开发者中不会受欢迎,我以为只有被雇主强迫的开发人员才会使用它们。

此事发生后,维护者和用户都纷纷撰写或要求制定LLM政策。Zig彻底禁止了LLM的使用。与此同时,Rust方面则采取了更为谨慎的态度。他们进行了一些民意调查,社区普遍反对LLM,但他们当时还没有准备好制定正式政策。

当他们最终提出方案时,其中包含了“臭名昭著”的审核政策:

对一些公关稿件的评论不得提及以下主题:

  • LLM的长期社会或经济影响
  • LLM的环境影响
  • 任何与LLM输出的版权状态有关的事情
  • 对使用LLM的人的道德评判

虽然在引发用户强烈反对后,该问题已被删除,但这件事本身就让我对 Rust 项目的未来失去了信任。我喜爱这门语言,但对其管理方式感到失望。

这项政策本身没问题。它几乎完全限制了LLM的使用,减少了大部分冗余代码。虽然远不及Zig的政策那么严苛,但也是可行的。不过,这次经历让我几年来第一次认真地研究起了Zig这门编程语言。

2026 年的 Zig


我首先注意到的是,这门语言仍然不稳定。当我尝试使用网上找到的 0.16.0 版本的代码示例时,发现它们已经过时了。我了解到,要想高效地使用 Zig,最好的方法是保留一份标准库源代码并熟悉它。

我对 Zig 的稳定性并不抱有任何幻想。Zig 0.17.0 即将发布,它又将破坏所有项目的构建系统。我理解维护者打算逐步提高 Zig 的稳定性,而这些破坏也是其中的一部分。

值得庆幸的是,自从 2020 年以来,这门语言并没有发生太大的变化。我发现我的大部分代码仍然适用。有的库中的一些内容有所改动,但代码易于阅读,我很快就上手了。

于是我相信,六年之后,今天的 Zig 代码仍然会同样易于识别。

我还注意到 Zig 现在也有了包管理器。我记得我离开的时候它还在开发中。我以前用的是 Git 子模块来管理依赖。现在的内置工具好用多了。项目可以通过 Git 和 tar 包定义依赖。vendor 也非常方便。

一切都运行得非常流畅。

目前 Zig 的生态系统还不够完善,但这从来都不是 Zig 的目标。Zig 项目没有官方的软件包仓库是有原因的。我们不需要另一个 NPM 或 crates.io。对我来说,Zig 已经达到了完美的平衡。

内存不安全


我知道 Zig 无法提供像 Rust 那样全面的内存安全保证。这是他们为了追求简洁而做出的权衡。Rust 仿射类型的复杂性带来的安全收益并不值得。

这并不是说放弃了安全性,Zig比不安全的 Rust 代码更要安全。因此,当你发现自己无论如何都必须编写不安全的 Rust 代码时,Zig 可能是一个更好的选择。

Zig 也在努力提升语言的安全性。他们的方法侧重于发布模式,而非代码中的不安全部分。目前,Zig 的 ReleaseSafe 模式在断言失败时会崩溃并初始化所有内存。但作者Andrew Kelley 希望进一步改进,将 ReleaseSafe 与Fil-C等工具集成。虽然这无法提供像 Rust 那样的编译时内存安全(假设你避免使用 `use` unsafe),但也不会像某些人所说的那样导致严重的安全隐患。

内存安全是一个连续乐谱,没有一种内存安全方法适用于所有情况。Zig 的做法是在运行时尽可能确保 ReleaseSafe 的安全性,然后进行测试和模糊测试以确保其正确性。任何未经检查的非法行为都应该在此过程中被发现。在验证其正确性之后,该二进制文件就可以安全地以其他发布模式发布。

这种方法相比 Rust 的模型有一些缺点,但并非完全逊色,尤其是在 Zig 追求 Rust 梦寐以求的简洁性方面。

编程语言有很多种,你可以选择最适合你用例的那一种。如果编译时内存安全值得你付出复杂的类型系统和较长的编译时间,那就去做吧。但这并非适用于所有人、所有情况。

Zig 的内存安全模型也延伸到了其断言理念中。在 ReleaseFast 模式下,Zig 不会禁用断言,而是相信您已经完成了必要的测试,证明断言正确且相关路径不可达,从而允许 Zig 优化代码。

Zig 要求完美,它也提供了实现完美的工具。

结语


因此,Zig有了标准库和版本更新日志,我已经准备好用它解决遇到的任何软件问题。如果不想处理底层细节,我会使用常用的脚本语言,但 Zig 将是我未来软件开发的强大动力。

我应该也不会一直使用 Zig。如果需要 Rust 的稳定性或类型系统,我会坚定选择它。我也有可能彻底改变对 Zig 的看法,多种编程语言可以而且应该共存。

但是Zig所代表的软件愿景与我产生了共鸣。它以用户为中心,并非忽视软件质量,而是重视软件质量。人们理应拥有可靠、强大的软件。在如今这个软件质量参差不齐的时代,这一点尤为重要。

作者:聆听音乐的鱼

评论

我要赞赏作者

请扫描二维码,使用微信支付哦。

分享到微信