Async-await 进入 Beta 阶段!

2019 年 9 月 30 日 · Niko Matsakis

重大消息!截至撰写本文时,**Rust Beta 通道已提供 async-await 的语法支持!** 它将在预计于 **2019 年 11 月 7 日** 发布的 1.39 版本中提供。一旦 async-await 进入稳定版,这将标志着 **为 Rust 启用高效且符合人体工程学原理的异步 I/O 的多年努力的顶峰**。然而,这并不意味着道路的终点:在抛光方面(我们今天得到的一些错误消息,嗯,不太好)和功能集方面(特质中的 async fn,有人吗?)还有更多工作要做。

(如果您不熟悉 async-await 是什么,不要绝望!本文后面将介绍入门知识和其他细节!)

生态系统中 async-await 支持快速增长

但 async-await 从来就不是全部故事。要充分利用 async-await,您还需要强大的库和充满活力的生态系统。**幸运的是,您有很多不错的选择,而且它们还在不断改进:**

重构 Rust 组织中的异步 I/O

现在 async-await 即将进入稳定版,我们正在利用这个机会对 Rust 团队结构进行一些调整。当前结构包括两个工作组:异步基础工作组,专注于构建核心语言支持,以及 异步生态系统工作组,专注于支持生态系统发展。

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

**同时,异步基础工作组 将继续存在,但重点将有所转变。** 现在 async-await 正在走向稳定,重点将放在抛光上,例如改进诊断、修复较小的错误,以及改进文档,例如 异步书籍。一旦在这方面取得进展,我们将考虑接下来要实现哪些功能。

(旁注:这是我们第一次选择解散工作组,我们意识到我们没有为此制定正式的政策。我们已 创建了一个问题,与 治理工作组 协商未来如何处理此类情况。)

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 的结果并传播错误。它还有助于使方法链变得轻松。

零成本 futures

Rust futures 与其他语言中的 futures 之间的另一个区别是,它们基于“轮询”模型,这使得它们 **零成本**。在其他语言中,调用异步函数会立即创建一个 future 并将其安排执行:等待 future 实际上并不需要它执行。但这意味着为创建的每个 future 都会产生一些开销。

相反,在 Rust 中,调用异步函数本身不会进行任何调度,这意味着我们可以组合一个复杂的 future 嵌套,而不会产生每个 future 的成本。但是,作为最终用户,您会注意到的一点是 **futures 感觉“懒惰”**:它们在您等待它们之前不会执行任何操作。

如果您想更深入地了解 futures 在幕后是如何工作的,请查看 异步书籍的 executor 部分,或观看 withoutboatsRust LATAM 2019 上关于此主题的 精彩演讲

总结

总之,如果您有兴趣在 Rust 中使用异步 I/O,现在是一个非常激动人心的时刻!随着 async-await 语法在 11 月进入稳定版,编写 futures 将比以往任何时候都更容易(特别是如果您过去尝试过使用基于组合器的 futures,您会发现 async-await 与 Rust 的借用系统更好地集成)。此外,生态系统中现在已经提供了一些很棒的运行时和其他库来使用。所以,开始动手构建吧!

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