-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1250 from adamchalmers/option-question-mark
Fix #1110: add examples of ? and Option
- Loading branch information
Showing
2 changed files
with
56 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# 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`. | ||
|
||
```rust,editable | ||
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. | ||
|
||
```rust,editable | ||
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)); | ||
} | ||
``` |