In Rust, a Future is like a placeholder for a value that will be available later. It represents a task that is still running or waiting, for example, downloading data, reading a file, or making an API call, and will eventually complete with a result.
In Rust, futures are a core concept of asynchronous programming. The key point is that Futures allow your program to keep running without waiting for that task to finish.
It’s like ordering food at a restaurant, you place your order (start a future), and when the food is ready, the server delivers it (the future resolves).
Futures are the foundation of Rust’s asynchronous programming model. They make it possible to write non-blocking code that runs efficiently without holding up other tasks.
How Futures Work in Rust
A Future implements the Future trait from the std::future module, for example:
pub trait Future {
type Output; // The type of value this future will produce
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output>;
}
- Output: Defines the type of value the future will eventually give.
- poll(): Checks if the future is ready. If it isn’t, Rust’s executor will try again later.
How To Create a Future In Rust?
In Rust, a Future represents a value that will be available later. You can easily create one using the async keyword.
Example: A Simple Future
async fn my_future() -> u32 {
42
}
#[tokio::main]
async fn main() {
let result = my_future().await;
println!("The future resolved with: {}", result);
}
Chaining Futures with .then()
The .then() method lets you take the result of one future and pass it to the next asynchronous operation.
Example: Chaining Futures
use futures::future;
#[tokio::main]
async fn main() {
let future = future::ready(10); // Creates a future that resolves immediately with 10
let result = future.then(|value| async move {
value * 2 // Multiply the result by 2 in the next future
}).await;
println!("Result: {}", result);
}
- future::ready(10): Creates a future that is immediately ready with the value 10.
- .then(|value| async move { … }): Takes the value from the first future (10) and runs another asynchronous block.
How To Combine Multiple Futures?
In Rust, you can run multiple asynchronous tasks at the same time using methods like tokio::join!.
Example: Running Futures Concurrently
use tokio::time::{sleep, Duration};
async fn task_one() {
sleep(Duration::from_secs(1)).await;
println!("Task one completed");
}
async fn task_two() {
sleep(Duration::from_secs(2)).await;
println!("Task two completed");
}
#[tokio::main]
async fn main() {
// Run both futures at the same time
tokio::join!(task_one(), task_two());
println!("Both tasks completed");
}
Output:
Task one completed
Task two completed
Both tasks completed
Explanation:
- task_one() and task_two(): Two async functions that simulate work by sleeping for 1 and 2 seconds, respectively.
How To Use Custom Futures?
You can also define custom futures by implementing the Future trait. Your custom future can keep track of its internal state to determine if it’s ready to produce a value or if it needs more time (Poll::Pending vs Poll::Ready).
Example: A Simple Custom Future
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
struct MyFuture {
step: u8,
}
impl Future for MyFuture {
type Output = u32;
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.step == 0 {
self.step += 1;
Poll::Pending // Future is not ready yet
} else {
Poll::Ready(42) // Future has completed with a value
}
}
}
#[tokio::main]
async fn main() {
let my_future = MyFuture { step: 0 };
let result = my_future.await;
println!("Custom future resolved with: {}", result);
}
Error Handling in Futures
You can handle errors in futures using the Result type and .await.
Example: Future with Error Handling
async fn fetch_data() -> Result<String, &'static str> {
Ok("Data fetched successfully".to_string())
}
#[tokio::main]
async fn main() {
match fetch_data().await {
Ok(data) => println!("{}", data),
Err(e) => println!("Error: {}", e),
}
}
Learn Other Topics About Rust
- What are threads in Rust?
- What is concurrency in Rust?
- What is error handling in Rust?
- What is an HashMap in Rust?
- What is an Iterator in Rust?
- What is Mutex in Rust?
- What is Async in Rust?

M.Sc. (Information Technology). I explain AI, AGI, Programming and future technologies in simple language. Founder of BoxOfLearn.com.