async fn
- Rust course
- Advanced
- Lesson 1/81
- 4 min
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.
Practice 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")).
Starter code
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, Waker};
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;
}
}
}
async fn selam(ad: &str) -> String {
format!("Merhaba {ad}")
}
fn main() {
println!("{}", block_on(selam("Ece")));
}Expected output
Merhaba Ece
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 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" Correct answer
- The text is printed
- Compile error
Explanation: Futures are lazy; they do no work unless awaited or handed to an executor.
2 Async function
____ fn selam(ad: &str) -> String {
format!("Merhaba {ad}")
}
async fn selam(ad: &str) -> String {
format!("Merhaba {ad}")
}
Explanation: An async fn returns a Future when called.
3 Concept and meaning
| Term | Meaning |
|---|---|
async fn |
Returns a Future |
Future |
A value to come later |
poll |
Advance one step |
executor |
Drives futures |