Unpacking Options with ?

RustRustBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we explore the use of the ? operator in Rust, which allows for easy unpacking of Option values without the need for nested match statements. The ? operator can be used to quickly return the underlying value if the Option is Some, or terminate the function and return None if the Option is None. This operator can be chained together to make code more readable and concise.

Note: If the lab does not specify a file name, you can use any file name you want. For example, you can use main.rs, compile and run it with rustc main.rs && ./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("`Rust`")) -.-> rust/BasicConceptsGroup(["`Basic Concepts`"]) rust(("`Rust`")) -.-> rust/DataTypesGroup(["`Data Types`"]) rust(("`Rust`")) -.-> rust/FunctionsandClosuresGroup(["`Functions and Closures`"]) rust(("`Rust`")) -.-> rust/MemorySafetyandManagementGroup(["`Memory Safety and Management`"]) rust(("`Rust`")) -.-> rust/DataStructuresandEnumsGroup(["`Data Structures and Enums`"]) rust(("`Rust`")) -.-> rust/ErrorHandlingandDebuggingGroup(["`Error Handling and Debugging`"]) rust(("`Rust`")) -.-> rust/AdvancedTopicsGroup(["`Advanced Topics`"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("`Variable Declarations`") rust/DataTypesGroup -.-> rust/integer_types("`Integer Types`") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("`Function Syntax`") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("`Expressions and Statements`") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("`Lifetime Specifiers`") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("`Method Syntax`") rust/ErrorHandlingandDebuggingGroup -.-> rust/error_propagation("`Error Propagation`") rust/AdvancedTopicsGroup -.-> rust/traits("`Traits`") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("`Traits for Operator Overloading`") subgraph Lab Skills rust/variable_declarations -.-> lab-99235{{"`Unpacking Options with ?`"}} rust/integer_types -.-> lab-99235{{"`Unpacking Options with ?`"}} rust/function_syntax -.-> lab-99235{{"`Unpacking Options with ?`"}} rust/expressions_statements -.-> lab-99235{{"`Unpacking Options with ?`"}} rust/lifetime_specifiers -.-> lab-99235{{"`Unpacking Options with ?`"}} rust/method_syntax -.-> lab-99235{{"`Unpacking Options with ?`"}} rust/error_propagation -.-> lab-99235{{"`Unpacking Options with ?`"}} rust/traits -.-> lab-99235{{"`Unpacking Options with ?`"}} rust/operator_overloading -.-> lab-99235{{"`Unpacking Options with ?`"}} end

Unpacking options with ?

You can unpack Options by using match statements, but it's often easier to use the ? operator. If x is an Option, then evaluating x? will return the underlying value if x is Some, otherwise it will terminate whatever function is being executed and return None.

fn next_birthday(current_age: Option<u8>) -> Option<String> {
    // If `current_age` is `None`, this returns `None`.
    // If `current_age` is `Some`, the inner `u8` gets assigned to `next_age`
    let next_age: u8 = current_age? + 1;
    Some(format!("Next year I will be {}", next_age))
}

You can chain many ?s together to make your code much more readable.

struct Person {
    job: Option<Job>,
}

#[derive(Clone, Copy)]
struct Job {
    phone_number: Option<PhoneNumber>,
}

#[derive(Clone, Copy)]
struct PhoneNumber {
    area_code: Option<u8>,
    number: u32,
}

impl Person {

    // Gets the area code of the phone number of the person's job, if it exists.
    fn work_phone_area_code(&self) -> Option<u8> {
        // This would need many nested `match` statements without the `?` operator.
        // It would take a lot more code - try writing it yourself and see which
        // is easier.
        self.job?.phone_number?.area_code
    }
}

fn main() {
    let p = Person {
        job: Some(Job {
            phone_number: Some(PhoneNumber {
                area_code: Some(61),
                number: 439222222,
            }),
        }),
    };

    assert_eq!(p.work_phone_area_code(), Some(61));
}

Summary

Congratulations! You have completed the Unpacking Options With ? lab. You can practice more labs in LabEx to improve your skills.

Other Rust Tutorials you may like