Purpose: Represents an optional value—either Some(T) or None.
- When a value might be absent (e.g., searching for an item in a list).
- Safer alternative to
nullornil.
enum Option<T> {
Some(T), // A value exists
None, // No value
}| Method | Description |
|---|---|
unwrap() |
Returns the value inside Some or panics if None. |
unwrap_or(default) |
Returns the value or a default if None. |
expect(msg) |
Like unwrap(), but with a custom panic message. |
map(f) |
Applies function f to the contained Some value. |
and_then(f) |
Chains Option-returning functions (like flat_map). |
is_some() |
Returns true if the Option is Some. |
is_none() |
Returns true if the Option is None. |
as_ref() |
Converts Option<T> to Option<&T>. |
ok_or(E) |
Converts Option<T> to Result<T, E>, mapping None to Err(E). |
fn find_index(haystack: &[i32], needle: i32) -> Option<usize> {
haystack.iter().position(|&x| x == needle)
}
let numbers = vec![1, 2, 3];
assert_eq!(find_index(&numbers, 2), Some(1));
assert_eq!(find_index(&numbers, 5), None);Purpose: Represents success (Ok(T)) or failure (Err(E)).
- Error handling (e.g., file I/O, parsing).
- Explicitly forces handling of both success and failure cases.
enum Result<T, E> {
Ok(T), // Success, contains a value
Err(E), // Failure, contains an error
}| Method | Description |
|---|---|
unwrap() |
Returns the value inside Ok or panics if Err. |
unwrap_or(default) |
Returns the value or a default if Err. |
expect(msg) |
Like unwrap(), but with a custom panic message. |
map(f) |
Applies function f to the contained Ok value. |
map_err(f) |
Applies function f to the contained Err value. |
and_then(f) |
Chains Result-returning functions (like flat_map). |
is_ok() |
Returns true if the Result is Ok. |
is_err() |
Returns true if the Result is Err. |
? operator |
Propagates errors: returns Ok value or early-returns Err. |
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
Err(String::from("Division by zero"))
} else {
Ok(a / b)
}
}
assert_eq!(divide(4.0, 2.0), Ok(2.0));
assert_eq!(divide(4.0, 0.0), Err(String::from("Division by zero")));Both Option and Result work seamlessly with match and if let.
match find_index(&numbers, 2) {
Some(index) => println!("Found at index: {}", index),
None => println!("Not found"),
}
match divide(4.0, 0.0) {
Ok(result) => println!("Result: {}", result),
Err(e) => println!("Error: {}", e),
}if let Some(index) = find_index(&numbers, 2) {
println!("Found at index: {}", index);
}OptiontoResult:let some_value: Option<i32> = Some(42); let result: Result<i32, &str> = some_value.ok_or("No value");
ResulttoOption:let ok_result: Result<i32, &str> = Ok(42); let option: Option<i32> = ok_result.ok();
- Purpose: Simplifies error propagation.
- Behavior:
- Unwraps
Okvalues. - Early-returns
Errvalues (in functions returningResult). - Works similarly for
Option(early-returnsNone).
- Unwraps
fn compute() -> Result<i32, String> {
let a = divide(4.0, 2.0)?;
let b = divide(a, 0.5)?;
Ok(b as i32)
}fn first_even(numbers: &[i32]) -> Option<i32> {
numbers.iter().find(|&&x| x % 2 == 0).copied()
}- Explicitness: Forces developers to handle absence or failure.
- Safety: Eliminates null pointer exceptions and unchecked errors.
- Composability: Methods like
map,and_then, and?enable clean, functional-style code.
- Avoid
unwrap(): Prefermatch,if let, or?for robust error handling. - Use
?for Propagation: Simplifies chaining fallible operations. - Custom Error Types: Use enums to define rich error types for
Result.#[derive(Debug)] enum MathError { DivisionByZero, NegativeRoot, }