Unpacking options with ? - Rust By Example
Description: A description

# Unpacking options with `?`

You can unpack `Option`s 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?;
        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));
    }