title: Result
Result<T, E> is Rust’s way of handling operations that can fail. Instead of throwing exceptions, functions return a Result that is either a success value or an error — and the compiler forces you to deal with both.
What it looks like
Result is an enum with two variants:
enum Result<T, E> {
Ok(T), // success, contains the value
Err(E), // failure, contains the error
}A function that returns Result
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
Err(String::from("cannot divide by zero"))
} else {
Ok(a / b)
}
}Handling a Result with match
match divide(10.0, 2.0) {
Ok(result) => println!("result: {result}"),
Err(e) => println!("error: {e}"),
}if let — a shorter alternative
When you only care about the success case:
if let Ok(result) = divide(10.0, 2.0) {
println!("result: {result}");
}Common methods
let result: Result<i32, String> = Ok(42);
result.is_ok(); // true
result.is_err(); // false
result.unwrap(); // returns 42, panics if Err — avoid in production
result.unwrap_or(0); // returns 42, falls back to 0 if Err
result.unwrap_or_else(|e| { log(e); 0 }); // handle error and provide fallback
// transform the Ok value without unwrapping
result.map(|n| n * 2); // Ok(84)
// transform the Err value
result.map_err(|e| format!("wrapped: {e}"));The ? operator
The most common way to handle Result in real code. In a function that returns Result, ? will return the error early if the operation failed, otherwise unwrap the success value:
use std::fs;
fn read_file(path: &str) -> Result<String, std::io::Error> {
let contents = fs::read_to_string(path)?; // returns Err early if file can't be read
Ok(contents)
}Without ? you’d need to match every single operation — ? makes chained fallible operations readable:
fn process() -> Result<String, std::io::Error> {
let config = fs::read_to_string("config.txt")?;
let data = fs::read_to_string("data.txt")?;
Ok(format!("{config}{data}"))
}Result vs Option
Option<T> | Result<T, E> | |
|---|---|---|
| Use when | a value may or may not exist | an operation may succeed or fail |
| Missing/failure case | None | Err(E) |
| Success case | Some(T) | Ok(T) |
| Carries error info | no | yes |
If you just need “something or nothing”, use Option. If you need to know why something failed, use Result.