一、Rust 的 async 关键字
Rust 语言的 async 关键字,它是 Rust 语言异步编程模型的核心组成部分。async 关键字用于标记一个函数或方法为异步的,这意味着该函数或方法内部将使用 await 关键字来等待异步操作(如 IO 操作、网络请求等)的完成,而不会阻塞当前线程的执行。
使用 async 关键字可以方便地编写出非阻塞的异步代码,从而大大提高程序的并发性能。在 Rust 的异步编程模型中,async 函数返回的是一个 Future 对象,这个对象代表了异步操作的结果。你可以使用 await 关键字来等待这个 Future 完成并获取其结果。
下面是一个简单的示例,展示了如何使用 async 和 await 关键字来编写异步函数:
use std::io;
use std::net::TcpStream;
use std::io::Read;
use tokio::runtime; async fn fetch_data_from_server(server: &str) -> Result<String, io::Error> { let mut stream = TcpStream::connect(server).await?; let mut buf = [0; 1024]; stream.read(&mut buf).await?; Ok(String::from_utf8_lossy(&buf[..]).into_owned())
} #[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> { let data = fetch_data_from_server("127.0.0.1:8080").await?; println!("{}", data); Ok(())
}
在这个例子中,fetch_data_from_server 函数被标记为 async,因为它内部使用了 await 来等待 TcpStream::connect 和 stream.read 这两个异步操作的完成。main 函数也被标记为 async,因为它调用了 fetch_data_from_server 这个异步函数。通过 await 关键字,我们可以非阻塞地等待这些异步操作的完成。
注意,为了运行上述代码,你需要使用 Tokio 或其他支持异步的 Rust 运行时库,因为标准库本身并不直接支持异步操作。Tokio 是 Rust 社区中非常流行的异步运行时库之一,它提供了丰富的异步 API 和工具来构建高效的异步应用程序。
二、async 与 Tokio
async 和 await 是 Rust 语言本身的一部分,而不是 Tokio 定义的。Rust 1.39 版本引入了这些关键字,作为对异步编程的原生支持。因此,你可以在任何 Rust 项目中使用 async 和 await,无需依赖特定的库或框架。
然而,async/await 语法本身并不直接执行异步操作;它们只是提供了一种编写异步代码的方式。要实际执行异步操作,你需要使用某种形式的异步运行时(runtime)。Tokio 是 Rust 中非常流行的异步运行时库之一,它提供了用于执行异步代码的基础设施,包括事件循环、任务调度等。
当你使用 async 定义一个函数时,该函数会返回一个 Future 对象。这个 Future 对象代表了异步操作的结果,但实际的异步执行是由运行时库(如 Tokio)负责的。在 Tokio 中,你可以使用 tokio::runtime::Runtime 或通过 #[tokio::main] 属性来创建和配置运行时,并在这个运行时中执行异步代码。
因此,虽然 async 和 await 是 Rust 语言自带的特性,但要充分利用它们,你通常需要与某种异步运行时库(如 Tokio)一起使用。Tokio 提供了丰富的 API 和工具来简化异步编程,但它并不是实现 async/await 语法的唯一方式。Rust 社区还有其他一些异步运行时库可供选择,但 Tokio 是目前最流行和广泛使用的库之一。