作为两门服务端的新语言,这些年受到越来越多的关注。有人调侃说,关注 Rust 的人中,很大一部分是从 Go 过来的。经常有人因为 Go 的一些设计和特质而质疑它,同时,Rust 常被誉为解决 Go 问题的几乎完美设计的替代方案。但实际上,这两门语言并不是直接竞争关系,不能直接互换,更多是互补。本文就带着大家看看两者的不同。
有一篇文章 《I want off Mr. Golang's Wild Ride》:https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride,以及围绕它的激烈讨论,不止一次遇到过诸如“Rust 是 Go 应该成为的样子”之类的陈述。这些讨论中观点,显然是由那篇文章推动的,似乎反应出 Go 有太多有问题的特性,而另一方面,Rust 是一个精心设计的 Go 替代品。
在我看来,这篇文章的讨论揭示了对这两种语言、它们解决的问题以及它们所针对的软件开发范式的严重误解。
01 文章对 Go 的批评
这篇文章主要批评 Go 的简单是一个谎言:标准库中的 API 向用户隐藏了复杂性,而没有真正解决它,这在极端情况下会产生完全错误的结果。以 Go 的 filepath.Ext
函数为例:它在某些情况下会产生不准确的结果。作为反例,这篇文章提到了 Rust std::path::extension
是产生完全正确结果的函数。
这种对 Go 在边缘情况下不准确的不满似乎是可以理解的。我们都知道,在编程中,只有正确和不正确,没有其他结果。因此,由于 Rust 提供了正确的结果,它显然是更好的语言。但事情真的这么简单吗?难道谷歌不能聘请高手来解决这个问题吗?
02 追根溯源
Go 和 Rust 被频繁地比较,因为它们都被宣传为系统编程语言,而且它们都是现代的编程语言,发布时间接近。但是,一旦你内化了它们的来源以及它们的设计目的,你很快就会发现它们是两种完全不同的语言。
Go 是一个 Google 项目,主要设计用于后端和网络服务。这些服务在可预测的、同质的、Unix 等基础设施中运行。谷歌完全控制着他们的基础设施,潜在的性能瓶颈可以通过在问题上投入更多的服务器来解决。
另一方面,Rust 是由 Mozilla 在非常不同的情况下启动的。Firefox 和 Servo 等项目是非常长寿的软件产品,必须在各种系统上运行。他们必须在不均匀、未知且可能充满恶意的环境中工作。因此,在每个系统上产生完全相同的结果对于这些应用程序至关重要。
03 不同的问题,不同的语言
谷歌和许多其他维护类似基础设施的公司通常必须应对以下挑战——虽然我对谷歌没有深入的了解,但其中一些可能被其庞大的规模放大了:
-
开发人员流动率高。
-
短迭代中的快节奏开发。
-
快节奏的组织扩展。
-
高度动态的基础设施和环境。
-
短期和可替换的服务。
Google 需要一种完全针对这些挑战量身定制的语言,并且不可避免地会设计出与满足 Mozilla 需求的语言不同的语言。
04 另一种范式
Go 和 Rust 不仅有不同的语言设计,它们还包含一种相反的软件开发方法。Rust 专注于高效率并为问题找到最漂亮的实现。为了实现这一点,与其他语言相比,它有着更陡峭的学习曲线。
相比之下——这就是大部分行业的现实——谷歌和许多其他公司不希望他们的开发人员在他们能够高效工作之前花 3 个月时间学习一门新语言。因此,Go 被有意设计为一种快速学习和使用的语言。它不一定是最有效或最漂亮的解决方案。它甚至不必在公司不使用的系统上工作。它只需要工作得足够好。
为什么?因为运行动态基础设施需要高度的自动化、标准化、监控、可观察性、弹性、可扩展性和安全性。对于不在这样的环境中工作的开发人员来说,这听起来可能很奇怪,但在日常业务中,重点往往是这些高级需求而不是代码本身。
05 底线
尽管乍一看 Go 和 Rust 似乎为类似场景提供了类似的好处,但它们是针对不同问题而设计的专业工具。就像大多数其他工具一样,一个并非比另一个“更好”。在寻找适合自己需求的新语言时,Google 和 Mozilla 都没有采取有偏见的方法。他们只是努力寻找最适合他们的解决方案——你也应该如此。