Result<T, E>

Represents an operation that can succeed with a value of type T or fail with an error of type E.

Variants

pub enum Result<T, E> {
    Ok(T),     // success
    Err(E),    // failure
}

Construction

let ok: Result<i32, String> = Result::Ok(42);
let err: Result<i32, String> = Result::Err("something went wrong");

Pattern Matching

match parse_number(input) {
    Result::Ok(n) => {
        println!("Parsed: {}", n);
    }
    Result::Err(e) => {
        println!("Error: {}", e);
    }
}

Common Methods

Checking

let succeeded = result.is_ok();    // bool
let failed = result.is_err();      // bool

Unwrapping

let value = result.unwrap();              // panics if Err
let value = result.unwrap_or(default);    // returns default if Err

Common Patterns

Functions That Can Fail

fn parse_file(path: String) -> Result<Data, String> {
    let content = read_file(path);
    match content {
        Result::Ok(text) => {
            // parse text into Data
            Result::Ok(data)
        }
        Result::Err(e) => {
            Result::Err("Failed to read file: " + e)
        }
    }
}

Error Accumulation

fn parse_all(inputs: Vec<String>) -> Result<Vec<i32>, Vec<String>> {
    let mut results: Vec<i32> = Vec::new();
    let mut errors: Vec<String> = Vec::new();

    for input in inputs {
        match parse_number(input) {
            Result::Ok(n) => results.push(n),
            Result::Err(e) => errors.push(e),
        }
    }

    if errors.is_empty() {
        Result::Ok(results)
    } else {
        Result::Err(errors)
    }
}

Memory Layout

Result<T, E> {
    is_ok: bool,           // discriminant
    union {
        ok: T,             // success value
        err: E,            // error value
    }
}