15.3 Error Propagation with the ? Operator

Explicit match expressions can become unwieldy when dealing with many sequential operations. The ? operator propagates errors automatically, reducing boilerplate while preserving explicit error handling.

15.3.1 Mechanism of the ? Operator

Using ? on an Err(e) immediately returns Err(e) from the current function. If the value is Ok(v), v is extracted and the function continues. An example:

#![allow(unused)]
fn main() {
use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();
    File::open("username.txt")?.read_to_string(&mut s)?;
    Ok(s)
}
}

The ? operator keeps the code concise and clear. Without it, you’d write multiple match statements or handle each failure manually.