Rust 是一种可扩展的语言 - matklad


在我上一篇关于Zig 和 Rust 的文章中,我提到 Rust 是一种“可扩展的语言”。让我稍微扩展一下。


垂直可扩展性
Rust 是垂直可扩展的,因为你可以在其中编写各种软件。
您可以编写一个高级的零分配图像压缩库,构建一个将库作为 HTTP SAAS 向世界公开的 Web 服务器,然后拼凑一个“脚本”来构建、测试并将其部署到如今人们部署软件的任何地方。
而且你只需要 Rust就可以。虽然它在整个技术栈的最低半部分表现出色,但它在其他任何地方也都很好。

横向可扩展性
Rust是可以横向扩展的,因为你可以很容易地在许多人和团队之间并行开发大型软件工件。Rust本身以惊人的速度发展,这对于这样一个松散的协调和长期人员不足的开源项目来说是令人惊讶的。这个相对较小的社区在短时间内成功地组建了一个全面的、可组合的、高质量的篮子生态系统。Rust是如此容易可靠地组成,甚至stdlib本身也不避讳从crates.io中提取依赖性。

Steve Klabnik写到了Rust的黄金法则:即函数签名是强制性和权威性的,并且明确定义了函数调用者和函数主体的接口。这种思想延伸到了语言的其他部分。

我最喜欢Rust的第二个特点(仅次于安全)是它的模块系统:它对库的概念有一流的支持。一个库被称为crate,是一棵模块树,是一个编译单位,也是一个原则性的可见性边界。模块可以包含循环依赖关系,但库总是形成一个有向无环图。没有全局的符号命名空间--库是匿名的,名字只出现在两个库之间的依赖边上,并且是下游crate的局部。

这个核心编译模型的好处被Cargo大大地放大了,它不是一个通用的任务运行器,而是对什么是Rust代码包的一个严格的规范:

  • 一个(库)crate、
  • 一个清单,用semver以声明的方式定义了包之间的依赖关系、
  • 生态系统范围内对依赖性规范的语义达成一致,并伴随着依赖性解析算法。

最重要的是,Cargo中完全没有办法控制实际的构建过程。build.rs文件可以用来提供额外的运行时输入,但调用rustc的是cargo。

同样,Cargo为可重复使用的Rust代码定义了一个严格的接口。生产者和消费者都必须遵守这些规则,这是没有办法的事。作为奖励,他们通过分工合作获得了一种超级权力。当我想使用serde-json时,我不需要在Slack中呼唤dtolnay,因为我们隐含地预先约定了一个共享的黄金规则。