Lesson 13 of 20

The Result Type

Result<T, E>

Result is used for recoverable errors. It is Rust's primary error handling mechanism:

enum Result<T, E> {
    Ok(T),
    Err(E),
}

Using Result

fn parse_number(s: &str) -> Result<i32, String> {
    s.parse::<i32>().map_err(|e| e.to_string())
}

match parse_number("42") {
    Ok(n) => println!("Got {}", n),
    Err(e) => println!("Error: {}", e),
}

Key Methods

result.unwrap()          // panics on Err
result.unwrap_or(0)      // default on Err
result.is_ok()           // true if Ok
result.is_err()          // true if Err
result.map(|v| v * 2)    // transform Ok value
result.map_err(|e| ...)  // transform Err value

The ? Operator

In functions returning Result, ? propagates errors automatically:

fn read_and_parse(s: &str) -> Result<i32, String> {
    let n: i32 = s.parse().map_err(|e: std::num::ParseIntError| e.to_string())?;
    Ok(n * 2)
}

Custom Error Types

Define your own error enums for structured errors:

#[derive(Debug)]
enum AppError {
    ParseError(String),
    DivisionByZero,
}

Your Task

  1. checked_divide(a: f64, b: f64) -> Result<f64, MathError> — returns Err(MathError::DivisionByZero) if b is 0.
  2. checked_sqrt(x: f64) -> Result<f64, MathError> — returns Err(MathError::NegativeSqrt) for negative x.
  3. parse_positive(s: &str) -> Result<u32, String> — parses a non-negative integer.
Rust (Miri) loading...
Loading...
Click "Run" to execute your code.