| The ? operator in Rust is a concise way to propagate errors. It simplifies error handling by either: - Returning the
Ok value if the result is successful. - Returning the
Err value if an error occurs, propagating it to the caller.
How It WorksWhen you apply the ? operator to a Result or Option: - If the value is
Ok(v), it extracts v and continues execution. - If the value is
Err(e), it returns Err(e) from the current function.
Example with Resultfn read_file(path: &str) -> std::io::Result<String> {
let content = std::fs::read_to_string(path)?; // If an error occurs, it propagates up
Ok(content) // Otherwise, returns the file content
}
fn main() {
match read_file("example.txt") {
Ok(content) => println!("File content: {}", content),
Err(err) => eprintln!("Error reading file: {}", err),
}
}
Example with Optionfn get_first_char(s: &str) -> Option<char> {
let first_char = s.chars().next()?; // Propagates `None` if `next()` returns `None`
Some(first_char)
}
fn main() {
let text = "hello";
match get_first_char(text) {
Some(c) => println!("First character: {}", c),
None => println!("String is empty"),
}
}
Requirements- The function using
? must return a Result or Option (or another compatible type). - If the function returns something else, you’ll need to convert the error type explicitly.
Why Use ?- Readable: Reduces boilerplate compared to
match statements. - Efficient: Automatically handles early returns for errors.
In short, ? is a shorthand for handling Result and Option values elegantly, making Rust's error-handling mechanism both safe and convenient. |