What is Async Programming?
Imagine you’re at a restaurant. Instead of waiting idly for your food, you browse your phone while the chef cooks. That’s asynchronous programming – doing other things while waiting for something to finish!
In Rust, async programming allows you to write non-blocking code, making your programs more efficient!
Declaring an Async Function
Rust provides the async
keyword to define asynchronous functions.
async fn hello_async() {
println!("Hello from async function!");
}
Adding async
before fn
makes the function return a Future instead of executing immediately.
BUT WAIT! Async functions don’t run by themselves – you need an executor!
Running an Async Function
To actually execute an async function, use .await
inside an async runtime like tokio or async-std.
use tokio::main;
#[tokio::main]
async fn main() {
hello_async().await;
}
#[tokio::main]
provides an async runtime. .await
tells Rust to pause execution until hello_async
is done.
Async with Return Values
Async functions can return values wrapped in Future<T>
.
async fn add(a: i32, b: i32) -> i32 {
a + b
}
#[tokio::main]
async fn main() {
let sum = add(3, 5).await;
println!("Sum: {}", sum);
}
.await
unwraps the Future<i32>
into an i32
.
Parallel Async Execution
Multiple async tasks can run concurrently!
use tokio::task;
#[tokio::main]
async fn main() {
let task1 = task::spawn(async {
println!("Task 1 running!");
});
let task2 = task::spawn(async {
println!("Task 2 running!");
});
task1.await.unwrap();
task2.await.unwrap();
}
task::spawn
runs tasks in parallel. await.unwrap()
ensures tasks complete.
When to Use Async?
When dealing with I/O-bound tasks (e.g., networking, file I/O). When performance is crucial – avoiding thread blocking! When you need efficient resource utilization.
But beware! Async Rust is not magic – it requires an executor and careful handling of lifetimes!
0 Comments