15.4 Error Propagation with the ? Operator

Writing match for every possible error can be verbose. The ? operator streamlines error propagation while preserving the explicitness Rust requires.

15.4.1 Mechanism of the ? Operator

If the result is Ok(T), the value T is extracted. If the result is Err(E), the function returns Err(E) immediately:

#![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)
}
}

Without ?, you would need explicit match blocks at each stage.