Async-await 进入 Beta!

2019 年 9 月 30 日 · Niko Matsakis

大新闻!截至撰写本文时,Async-await 的语法支持已在 Rust Beta 通道中可用! 它将在 1.39 版本中发布,预计发布日期为 2019 年 11 月 7 日。一旦 Async-await 进入稳定版,这将标志着 在 Rust 中实现高效且符合人体工程学的异步 I/O 的多年努力达到顶峰。然而,这并不意味着终点:仍然有更多工作要做,无论是在完善方面(今天我们遇到的一些错误消息,嗯,不太好)还是在功能集方面(有人想要 Trait 中的 async fn 吗?)。

(如果您不熟悉 Async-await 是什么,请不要绝望!本文后面有入门介绍和其他详细信息!)

生态系统中的 Async-await 支持正在快速增长

但 Async-await 从来都不是全部。要很好地利用 Async-await,您还需要强大的库和活跃的生态系统。**幸运的是,您有很多不错的选择,而且它们还在不断改进:**

重组 Rust 组织中的异步 I/O 工作

既然 Async-await 正在接近稳定版,我们正借此机会对 Rust 团队结构进行一些更改。当前的结构包括两个工作组:专注于构建核心语言支持的 Async Foundations WG,以及专注于支持生态系统发展的 Async Ecosystem WG

**然而,鉴于生态系统中正在进行的诸多活动,对 Async Ecosystem WG 的需求并没有那么多,因此我们决定将其解散。**我们将弃用 rustasync GitHub 组织areweasyncyet.rsarewewebyet.org 网站将迁移到主 rust-lang 组织,但其他项目的命运将由构建它们的人决定。其中一些可能会被弃用,其余的将移出去独立维护。

**与此同时,Async Foundations WG 将继续运作,但重点会转移。**既然 Async-await 正在走向稳定版,重点将放在完善方面,例如改进诊断信息、修复小错误以及改进文档,例如 Async Book。一旦在这方面取得进展,我们将考虑下一步要实现哪些功能。

(题外话:这是我们第一次决定解散一个工作组,我们意识到对此没有正式的政策。我们已与 治理工作组 创建了一个问题,以探讨未来的相关事宜。)

Async-await:快速入门

那么,Async-await 是什么?Async-await 是一种编写函数的方式,这些函数可以“暂停”,将控制权返回给运行时,然后从它们离开的地方继续执行。通常这些暂停是为了等待 I/O,但它还有很多其他用途。

您可能熟悉来自其他语言(例如 JavaScript 或 C#)的 async-await。Rust 中的此功能版本类似,但有一些关键区别。

要使用 Async-await,您首先要写 async fn 而不是 fn

async fn first_function() -> u32 { .. }

与普通函数不同,调用 async fn 并不会立即开始执行——而是返回一个 Future。这是一个等待执行的暂停计算。要实际执行 Future,您必须使用 .await 操作符

async fn another_function() {
    // Create the future:
    let future = first_function();
    
    // Await the future, which will execute it (and suspend
    // this function if we encounter a need to wait for I/O): 
    let result: u32 = future.await;
    ...
}

这个例子展示了 Rust 与其他语言的第一个区别:我们写 future.await 而不是 await future。这个语法与 Rust 的 ? 操作符更好地结合,用于传播错误(毕竟这在 I/O 中非常常见)。你可以简单地写 future.await? 来等待 Future 的结果并传播错误。它还有一个优点是使方法链变得无痛。

零成本 Future

Rust 的 Future 与其他语言的 Future 另一个区别是它们基于“poll”模型,这使得它们**零成本**。在其他语言中,调用异步函数会立即创建一个 Future 并安排它执行:等待 Future 并不是执行所必需的。但这意味着创建的每个 Future 都会有一些开销。

相比之下,在 Rust 中,调用异步函数本身不会进行任何调度,这意味着我们可以组合一个复杂的 Future 嵌套,而不会产生每个 Future 的成本。然而,作为最终用户,您会注意到的主要一点是,**Future 感觉“惰性”**:在您等待它们之前,它们什么也不做。

如果您想更深入地了解 Future 在底层是如何工作的,请查看 Async Book执行器部分,或者观看 withoutboatsRust LATAM 2019 上就此主题发表的精彩演讲

总结

总而言之,如果您对在 Rust 中使用异步 I/O 感兴趣,这是一个非常令人兴奋的时刻!Async-await 语法将于 11 月进入稳定版,编写 Future 将比以往任何时候都更容易(特别是如果您过去尝试过使用基于组合器的 Future,您会发现 Async-await 与 Rust 的借用系统集成得更好)。此外,生态系统中现在有许多出色的运行时和其他可用库可供使用。所以,行动起来,构建您的作品吧!

(哦,对了,如果您遇到令人困惑或意外的问题,请提交 Bug 报告,以便我们改进用户体验!)