async
and await
are key language features in Rust for writing asynchronous code. They were stabilized in the Rust 1.39.0 release.
Asynchronous programming is a way of writing programs that are able to do multiple things at the same time. It's particularly useful in situations where you need to handle many tasks at once, or when you have IO-bound tasks (like network requests) that often spend a lot of time waiting.
Here's how async
and await
work in Rust:
-
async : The
async
keyword in Rust is used to define an asynchronous function that returns a future. A future is a value that represents some computation that will complete in the future.Here is a simple async function:
rustasync fn hello() { println!("Hello, async world!"); }
This
hello
function, when called, will produce a future. To actually execute the code inside the function, the future needs to be run on an executor. -
await : The
await
keyword is used within async functions to wait for the result of a future. Unlike blocking in a traditional function, awaiting inside an async function allows other tasks to run.Here is an example of using
await
:rustasync fn hello() -> String { "Hello, async world!".to_string() } #[tokio::main] // or #[async_std::main] if you're using async-std async fn main() { let message = hello().await; println!("{}", message); }
In this example,
hello().await
causes themain
function to wait for thehello
function to finish, and then binds its result to themessage
variable.
Rust's async system works on a zero-cost abstraction principle, which means there should be no additional overhead for using these features.
Note that Rust's standard library does not provide an async runtime. You'll need to use a crate like tokio
or async-std
to provide an executor and other tools for working with async functions and futures. These are powerful libraries that provide async versions of many standard Rust features, along with additional tools for building async applications.
rust
use async_std::task::{sleep, spawn, block_on};
use std::{future::Future, time::Duration};
#[async_std::main]
async fn main() {
// do3();
// do4();
// let do3_span = spawn(do3);
// let do4_span = spawn(do4);
// do3_span.join().unwrap();
// do4_span.join().unwrap();
// let do3_async = spawn(do3());
// do4().await;
// do3_async.await;
let result = block_on(rust_study());
println!("{}", result); // Rust 学习目标:Programming
}
async fn lesson() -> String {
String::from("Rust")
}
fn study1() -> impl Future<Output = String> {
async {
let x = lesson().await;
x + " 学习目标:"
}
}
fn rust_study() -> impl Future<Output = String> {
let r = |x: String| async move {
let y: String = study1().await;
y + &*x
};
r(String::from("Programming"))
}
async fn do3() {
for i in 1..=5 {
println!("do3 {}", i);
sleep(Duration::from_millis(500)).await;
}
}
async fn do4() {
for i in 1..=5 {
println!("do4 {}", i);
sleep(Duration::from_millis(1000)).await;
}
}
// fn do3() {
// for i in 1..=5 {
// println!("do3 {}", i);
// sleep(Duration::from_millis(500));
// }
// }
// fn do4() {
// for i in 1..=5 {
// println!("do4 {}", i);
// sleep(Duration::from_millis(1000));
// }
// }