Rust
async fn
Define async functions with async fn.
async fn
When an async fn is called, its body doesn't run; instead it returns a Future. A future is "a computation that will produce a value later", and it waits until an executor drives it:
async fn selam(ad: &str) -> String {
format!("Merhaba {ad}")
}
let f = selam("Ece"); // nothing has run yet
// f: impl Future<Output = String>
Rust's standard library doesn't include an executor; real projects use a runtime like tokio. In the exercises we'll write a small block_on that polls the future until it completes.
The smallest executor
The core of an executor is polling the future until it returns Poll::Ready. When there's no pending work, no wake-up notification is needed, so an empty Waker is enough:
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;
}
}
}
Real runtimes, instead of a busy loop, put the thread to sleep until the future reports it's ready via the Waker.
Exercise First async function
Write the block_on executor above and the function async fn selam(ad: &str) -> String. Print the result of block_on(selam("Ece")).
Show example 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;
}
}
}
async fn selam(ad: &str) -> String {
format!("Merhaba {ad}")
}
fn main() {
println!("{}", block_on(selam("Ece")));
}
Test yourself
-
What happens if the line <code>selam("Ece");</code> is written on its own?
- The program waits
- A future is created but never runs; the compiler warns "unused future"
- The text is printed
- Compile error
Show answer
A future is created but never runs; the compiler warns "unused future" — Futures are lazy; they do no work unless awaited or handed to an executor.
-
Async function
____ fn selam(ad: &str) -> String {
format!("Merhaba {ad}")
}
Show answer
async fn selam(ad: &str) -> String {
format!("Merhaba {ad}")
}
-
Concept and meaning
- async fn
- Returns a Future
- Future
- A value to come later
- poll
- Advance one step
- executor
- Drives futures
Next lesson: await