Rust async/await 术语解释

1,320 阅读2分钟

事实是,其他编程语言中的async/await功能似乎比Rust中的更直接。例如,在JavaScript中,你可以直接使用他。但在Rust中,似乎有更多的组件,需要结合使用。

Tokio?Future?有一个Futures crate吗?运行时?所有这些是如何融入Rust中的async/await?

本篇旨在帮助理清开发人员在开始探索Rust中的异步编程时会遇到的一些术语。它将解释主要的组件部分,即:std::future::Futurefuturescrates,以及异步运行时,如tokio和async-std。让我们开始吧。

std::future::Future

异步编程的核心是最大化计算资源,尤其是IO绑定的计算。做到这一点的方法之一,是在计算过程中不直接执行,而是以暂停的形式写入,以后可以执行或暂停,或重试。

用来表达这种计算的类型就是 std::future::Future。例如,一个不直接执行的打印语句:

use std::future::Future;
fn future_print() -> impl Future<Output = ()> {
    async {
        println!("Hello World!");
    }
}

返回类型 impl Future<Output = ()> 表示这是一个可以返回任何实现std::future::Future trait 类型的函数。

要完全理解可能有点晦涩难懂的语法,请查看Rust书中的Trait部分。 std::future::Future是标准库的一部分,不需要依赖任何外部crate来访问它。

为了确认 future_print 不会直接执行,让我们试着在main中调用它,看看会发生什么。

use std::future::Future;

fn future_print() -> impl Future<Output = ()> {
    async {
        println!("Hello World!");
    }
}

fn main() {
    future_print();
}

输出结果如下:

warning: `async_await` (bin "async_await") generated 2 warnings
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/async_await`

Process finished with exit code 0

正如你所看到的,没有Hello World打印到控制台。确认std::future::Future表示已经描述过的计算,但没有直接执行,这就是Rust中异步编程的关键所在。

在实践中,通常没有必要直接使用std::future::Future类型作为返回类型。Rust有一个语法糖,以async关键字的形式,使代码不那么嘈杂。上面的代码片段可以重新写成:

async fn future_print() {
    println!("Hello World!");
}

fn main() {
    future_print();
}

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情