← Back to Rust Course | Chapter 10: Error Handling | Lesson 1 of 6

The Result Type

Result is Rust's way of saying an operation either worked and gives you an answer, or failed and tells you why.

What Is Result

Result<T, E> is an enum with two variants: Ok(value) for success carrying a T, and Err(error) for failure carrying an E. It's the standard way Rust represents fallible operations.

Example: What Is Result

markup
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("division by zero"))
    } else {
        Ok(a / b)
    }
}

fn main() {
    println!("{:?}", divide(10.0, 2.0));
}

Matching on Result

match lets you explicitly handle both the success and failure cases of a Result, extracting the value or the error as needed.

Example: Matching on Result

markup
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("division by zero"))
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(5.0, 0.0) {
        Ok(value) => println!("Result: {}", value),
        Err(e) => println!("Error: {}", e),
    }
}

Parsing Returns a Result

Many standard library operations that can fail, like parsing a string into a number, return a Result so the caller must decide how to handle a malformed input.

Example: Parsing Returns a Result

markup
fn main() {
    let input = "42";
    let parsed: Result<i32, _> = input.parse();
    match parsed {
        Ok(n) => println!("Parsed number: {}", n),
        Err(_) => println!("Could not parse"),
    }
}

Result vs Option

Option signals whether a value is present at all, while Result additionally carries information about why an operation failed, making it the better choice whenever the reason for failure matters.

Example: Result vs Option

markup
fn safe_divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err(String::from("cannot divide by zero"))
    } else {
        Ok(a / b)
    }
}

fn main() {
    println!("{:?}", safe_divide(10, 2));
    println!("{:?}", safe_divide(10, 0));
}
Common Mistakes
  1. Ignoring a Result returned by a function -- the compiler warns about an unused Result since errors could be silently dropped.
  2. Assuming Result and Option are interchangeable -- Result carries error information, while Option just signals absence.
  3. Trying to use the Ok value directly without matching or unwrapping the Result first.
Chapter Summary
  • Result<T, E> represents either success (Ok(value)) or failure (Err(error)).
  • Functions that can fail, like parsing or file I/O, typically return a Result instead of panicking directly.
  • match is the most explicit way to handle both the Ok and Err cases of a Result.
  • Rust's compiler warns when a Result is left unused, nudging you to handle potential errors.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.