Option

Option

std

Rust has no null. Instead, use std::option::Option⮳:

enum Option<T> {
  None,
  Some(T),
}

Every std::option::Option⮳ is either std::option::Option::Some⮳ and contains a value, or std::option::Option::None⮳, and does not.

fn main() {
    // `Some` is a variant of the `Option` enum that represents a value.
    let _some_number = Some(5);

    // `None` is another variant of the `Option` enum that represents the
    // absence of a value.
    let absent_number: Option<i32> = None;
    println!("{:?}", absent_number);
}

It is often used with match⮳, if let, or while let:

/// This function simulates baking a cake.
///
/// It takes an optional `sprinkles` argument, which determines
/// whether or not to add sprinkles to the cake.
///
/// Returns a string describing the cake.
fn bake_cake(sprinkles: Option<&str>) -> String {
    let mut cake = String::from("A delicious cake...");

    // Add required ingredients.

    // Handle optional sprinkles.
    if let Some(sprinkle_choice) = sprinkles {
        cake.push_str(
            format!(" with a sprinkle of {}", sprinkle_choice).as_str(),
        );
    } else {
        // sprinkles is `None`.
        cake.push_str(" ready for your decorating touch!");
    }
    cake
}

fn main() {
    print!("{}", bake_cake(Some("rainbow nonpareils")));
}

Use Adapters when Working with References

std

Extract the Value Contained in Option

std

These methods extract the contained value in an std::option::Option when it is the Some variant. If the std::option::Option⮳ is None:

Use Combinators

std

use std::fs;

/// Reads a file and returns its contents as a trimmed string.
///
/// # Arguments
///
/// * `filename` - The name of the file to read.
///
/// # Returns
///
/// Returns `Some(String)` containing the trimmed file contents if successful,
/// otherwise `None`.
fn read_file(filename: &str) -> Option<String> {
    fs::read_to_string(filename)
        // Convert `Result` to `Option`.
        .ok()
        // `and_then` applies a function to the wrapped value if it's `Some`.
        .and_then(|contents| Some(contents.trim().to_string()))
}

fn main() -> anyhow::Result<()> {
    let contents = read_file("temp/poem.txt");

    // Using `match` to process the returned Option.
    match contents {
        Some(poem) => println!("{}", poem),
        None => println!("Error reading file"),
    }
    Ok(())
}

See Also

  • Iterators.
  • Match.
  • Result.
  • Rust Patterns.