Languages: Python C C++ Go Java Ruby Rust Perl R ← Full TOC

← Rust Index

✅ Option & Result — Error handling without exceptions — the Rust way

Rust has no null and no exceptions. Option<T> represents a value that may be absent. Result<T,E> represents success or failure. The ? operator propagates errors ergonomically.

Docs: doc.rust-lang.org

📋 Types, Functions & Methods

NameSignatureDescription
Option::Some(v)Some(v): Option<T>A present value
Option::NoneNone: Option<T>An absent value
opt.unwrapfn unwrap(self) -> TReturn value or panic if None
opt.unwrap_orfn unwrap_or(self, default: T) -> TReturn value or default if None
opt.unwrap_or_elsefn unwrap_or_else(self, f: F) -> TReturn value or call f() if None
opt.mapfn map<U>(self, f: F) -> Option<U>Transform Some value, pass None through
opt.and_thenfn and_then<U>(self, f: F) -> Option<U>Chain Option-returning operations (flatMap)
opt.orfn or(self, optb: Option<T>) -> Option<T>Return self if Some else optb
opt.filterfn filter<P>(self, predicate: P) -> SelfKeep Some if predicate holds
opt.is_somefn is_some(&self) -> boolTrue if Some
opt.is_nonefn is_none(&self) -> boolTrue if None
opt.as_reffn as_ref(&self) -> Option<&T>Convert &Option<T> to Option<&T>
opt.takefn take(&mut self) -> Option<T>Take value out, leaving None
opt.ok_orfn ok_or<E>(self, err: E) -> Result<T,E>Convert Some to Ok, None to Err(err)
opt.flattenfn flatten(self) -> Option<T> where T: Option<U>Flatten Option<Option<T>> to Option<T>
Result::Ok(v)Ok(v): Result<T,E>Success value
Result::Err(e)Err(e): Result<T,E>Error value
res.unwrapfn unwrap(self) -> TReturn Ok value or panic
res.unwrap_orfn unwrap_or(self, default: T) -> TReturn Ok value or default
res.mapfn map<U,F>(self, op: F) -> Result<U,E>Transform Ok value
res.map_errfn map_err<F,O>(self, op: O) -> Result<T,F>Transform Err value
res.and_thenfn and_then<U,F>(self, op: F) -> Result<U,E>Chain Result-returning operations
res.is_okfn is_ok(&self) -> boolTrue if Ok
res.is_errfn is_err(&self) -> boolTrue if Err
? operatorexpr? : propagate Err/NoneReturn Err/None from current function if result is Err/None
res.ok()fn ok(self) -> Option<T>Convert Ok to Some, Err to None
From / Intotrait From<T> for UAuto-conversion used by ? operator to convert error types

💡 Example

Save as main.rs in a Cargo project and run with cargo run.

use std::num::ParseIntError;
use std::fmt;

#[derive(Debug)]
enum AppError {
    Parse(ParseIntError),
    Validation(String),
    Io(std::io::Error),
}

impl fmt::Display for AppError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            AppError::Parse(e)      => write!(f, "parse: {}", e),
            AppError::Validation(s) => write!(f, "validation: {}", s),
            AppError::Io(e)         => write!(f, "I/O: {}", e),
        }
    }
}
impl From<ParseIntError> for AppError { fn from(e: ParseIntError) -> Self { AppError::Parse(e) } }
impl From<std::io::Error> for AppError { fn from(e: std::io::Error) -> Self { AppError::Io(e) } }

fn parse_age(s: &str) -> Result<u8, AppError> {
    let n: i32 = s.trim().parse::<i32>()?;  // ? converts ParseIntError via From
    if n < 0 || n > 150 {
        return Err(AppError::Validation(format!("{} out of [0,150]", n)));
    }
    Ok(n as u8)
}

fn find_user(name: &str) -> Option<(&str, u8)> {
    [("Alice", 30u8), ("Bob", 25), ("Carol", 35)].iter().find(|(n,_)| *n == name).copied()
}

fn main() {
    // Result handling
    for input in &["25", "abc", "-1", "200"] {
        match parse_age(input) {
            Ok(age)  => println!("Valid age: {}", age),
            Err(e)   => println!("Error: {}", e),
        }
    }

    // Option chaining
    for name in &["Alice", "Dave", "Carol"] {
        let msg = find_user(name)
            .map(|(n, age)| format!("{} is {} years old", n, age))
            .unwrap_or_else(|| format!("{} not found", name));
        println!("{}", msg);
    }

    // ? in closure returning Result
    let result: Result<i32, AppError> = (|| {
        let content = std::fs::read_to_string("missing.txt")?;
        let n: i32  = content.trim().parse::<i32>()?;
        Ok(n * 2)
    })();
    println!("File result: {:?}", result);
}
// cargo run

← std::thread  |  🏠 Index