Channels ](../../std_misc/channels.html)
    4. [ **20.3.** Path ](../../std_misc/path.html)
    5. [ **20.4.** File I/O ](../../std_misc/file.html) â± 
    6.       1. [ **20.4.1.** open ](../../std_misc/file/open.html)
      2. [ **20.4.2.** create ](../../std_misc/file/create.html)
      3. [ **20.4.3.** read lines ](../../std_misc/file/read_lines.html)
    7. [ **20.5.** Child processes ](../../std_misc/process.html) â± 
    8.       1. [ **20.5.1.** Pipes ](../../std_misc/process/pipe.html)
      2. [ **20.5.2.** Wait ](../../std_misc/process/wait.html)
    9. [ **20.6.** Filesystem Operations ](../../std_misc/fs.html)
    10. [ **20.7.** Program arguments ](../../std_misc/arg.html) â± 
    11.       1. [ **20.7.1.** Argument parsing ](../../std_misc/arg/matching.html)
    12. [ **20.8.** Foreign Function Interface ](../../std_misc/ffi.html)
  41. [ **21.** Testing ](../../testing.html) â± 
  42.     1. [ **21.1.** Unit testing ](../../testing/unit_testing.html)
    2. [ **21.2.** Documentation testing ](../../testing/doc_testing.html)
    3. [ **21.3.** Integration testing ](../../testing/integration_testing.html)
    4. [ **21.4.** Dev-dependencies ](../../testing/dev_dependencies.html)
  43. [ **22.** Unsafe Operations ](../../unsafe.html) â± 
  44.     1. [ **22.1.** Inline assembly ](../../unsafe/asm.html)
  45. [ **23.** Compatibility ](../../compatibility.html) â± 
  46.     1. [ **23.1.** Raw identifiers ](../../compatibility/raw_identifiers.html)
  47. [ **24.** Meta ](../../meta.html) â± 
  48.     1. [ **24.1.** Documentation ](../../meta/doc.html)
    2. [ **24.2.** Playground ](../../meta/playground.html)

__ __

  * Light (default) 
  * Rust 
  * Coal 
  * Navy 
  * Ayu 

__

#  Rust By Example

[ __ ](../../print.html "Print this book") [ __ ](https://github.com/rust-
lang/rust-by-example "Git repository") [ __ ](https://github.com/rust-
lang/rust-by-example/edit/master/src/std/result/question_mark.md "Suggest an
edit")

#  ` ? `

Chaining results using match can get pretty untidy; luckily, the ` ? `
operator can be used to make things pretty again. ` ? ` is used at the end of
an expression returning a ` Result ` , and is equivalent to a match
expression, where the ` Err(err) ` branch expands to an early ` return
Err(From::from(err)) ` , and the ` Ok(ok) ` branch expands to an ` ok `
expression.

    
    
    mod checked {
        #[derive(Debug)]
        enum MathError {
            DivisionByZero,
            NonPositiveLogarithm,
            NegativeSquareRoot,
        }
    
        type MathResult = Result<f64, MathError>;
    
        fn div(x: f64, y: f64) -> MathResult {
            if y == 0.0 {
                Err(MathError::DivisionByZero)
            } else {
                Ok(x / y)
            }
        }
    
        fn sqrt(x: f64) -> MathResult {
            if x < 0.0 {
                Err(MathError::NegativeSquareRoot)
            } else {
                Ok(x.sqrt())
            }
        }
    
        fn ln(x: f64) -> MathResult {
            if x <= 0.0 {
                Err(MathError::NonPositiveLogarithm)
            } else {
                Ok(x.ln())
            }
        }
    
        // Intermediate function
        fn op_(x: f64, y: f64) -> MathResult {
            // if `div` "fails", then `DivisionByZero` will be `return`ed
            let ratio = div(x, y)?;
    
            // if `ln` "fails", then `NonPositiveLogarithm` will be `return`ed
            let ln = ln(ratio)?;
    
            sqrt(ln)
        }
    
        pub fn op(x: f64, y: f64) {
            match op_(x, y) {
                Err(why) => panic!("{}", match why {
                    MathError::NonPositiveLogarithm
                        => "logarithm of non-positive number",
                    MathError::DivisionByZero
                        => "division by zero",
                    MathError::NegativeSquareRoot
                        => "square root of negative number",
                }),