liveBook · Manning

Question mark operator

As explained in Code Like a Pro in Rust

The question mark operator is Rust syntax that propagates an error from a Result or Option expression and otherwise produces its successful value.

Use `?` in functions that return `Result` to keep the successful value and return early on an error. It replaces repetitive error checks when propagation is the right response. Functions that may have no value can instead return `Option`, allowing `?` to propagate absence. section 4.6 section 6.1

fn read_file(name: &str) -> Result<String, Error> {
    use std::fs::File;
    use std::io::prelude::*;
 
    let mut file = File::open(name)?;      #1
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;   #2
    Ok(contents)
}

The file-reading function uses `?` after both `File::open` and `read_to_string`. If either operation fails, the function returns early; otherwise, it returns the file contents. section 4.6

impl From<std::io::Error> for Error {
   fn from(other: std::io::Error) -> Self {
       Self {
           message: other.to_string(),
       }
   }
}

Both file operations produce `std::io::Error`, but the function returns its own `Error` type. This `From` implementation supplies the conversion needed at each `?`. section 4.6

Use propagation deliberately:

  • Return a crate-specific error type when callers need to identify where an error originated, and provide `From` conversions for errors passed through `?`. section 4.6
  • Handle an error explicitly when the response depends on the particular function; `?` is most useful for generic propagation. section 6.1
  • Use `expect()` with an explanatory message if an unexpected result should panic, rather than treating it as an error to propagate. section 6.1

How Code Like a Pro in Rust covers it

How deep it goes
Shows two propagation sites and the `From` conversion they require, while leaving function-specific error handling to explicit code.
Examples
Uses a file-reading function that opens a file, reads it into a string, and converts I/O errors to a custom error.
What it assumes
Assumes familiarity with functions returning `Result` or `Option` and shows the conversion needed when returned error types differ.
What you can do after
Practice/perform early error propagation in fallible functions, adding `From` conversions when their error types differ.
How it connects
Connects `Result` and `Option` return types with the `From` trait for error conversion.

Also explained in

Compare how 4 books explain question mark operator →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Code Like a Pro in Rust. The section links point to the parts of the book it draws on.