async block
- Rust course
- Advanced
- Lesson 4/81
- 4 min
Create an anonymous future with an async {} block.
async blocks
An async { .. } block creates a future on the spot without defining a function. With move it takes ownership of the values it captures; it's needed for futures sent to a task:
let ad = String::from("Ece");
let f = async move {
format!("{ad} hazır")
};
// ad is now inside f
let sonuc = block_on(f);Async blocks resemble closures but aren't called; when evaluated, they produce a future.
Async closures
To return a future from a closure, making the body an async block is enough. With Rust 1.85 the async || .. syntax became stable too:
let ikile = |x: u32| async move { x * 2 };
let f = ikile(21); // Future
println!("{}", block_on(f)); // 42This pattern is common when starting asynchronous work for each item in a collection.
Practice Async blocks
Create a future that captures let ad = String::from("Ece"); with an async move block and produces "Ece hazır". Also call the closure |x: u32| async move { x * 2 } with 21. Get both results with block_on and print them separated by a space.
Starter code
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, Waker};
fn block_on<F: Future>(f: F) -> F::Output {
let mut f = pin!(f);
let mut cx = Context::from_waker(Waker::noop());
loop {
if let Poll::Ready(v) = f.as_mut().poll(&mut cx) {
return v;
}
}
}
fn main() {
// buraya yaz
}Sample solution
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, Waker};
fn block_on<F: Future>(f: F) -> F::Output {
let mut f = pin!(f);
let mut cx = Context::from_waker(Waker::noop());
loop {
if let Poll::Ready(v) = f.as_mut().poll(&mut cx) {
return v;
}
}
}
fn main() {
let ad = String::from("Ece");
let f = async move { format!("{ad} hazır") };
let ikile = |x: u32| async move { x * 2 };
println!("{} {}", block_on(f), block_on(ikile(21)));
}Expected output
Ece hazır 42
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 If <code>?</code> is used inside an async block, where does the error go?
- It panics
- It can't be used
- To the block's own result; it doesn't exit the surrounding function Correct answer
- It exits the surrounding function
Explanation: An async block is a separate body with its own return point; its type often needs to be stated explicitly: async { Ok::<_, String>(..) }.
2 Move ownership
let ad = String::from("Ece");
let f = async ____ {
format!("{ad} hazır")
};
let ad = String::from("Ece");
let f = async move {
format!("{ad} hazır")
};
Explanation: async move moves the captured values into the future.
3 Syntax and result
| Term | Meaning |
|---|---|
async { 1 } |
Future<Output = i32> |
async move { ad } |
Owns ad |
|x| async move { x * 2 } |
Closure returning a future |
block_on(async { 7 }) |
7 |