Skip to content

Commit

Permalink
Merge pull request #1250 from adamchalmers/option-question-mark
Browse files Browse the repository at this point in the history
Fix #1110: add examples of ? and Option
  • Loading branch information
marioidival authored Sep 10, 2019
2 parents 1626088 + e9464a2 commit a72e9d2
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
- [Error handling](error.md)
- [`panic`](error/panic.md)
- [`Option` & `unwrap`](error/option_unwrap.md)
- [Unpacking options with ?](error/option_unwrap/question_mark.md)
- [Combinators: `map`](error/option_unwrap/map.md)
- [Combinators: `and_then`](error/option_unwrap/and_then.md)
- [`Result`](error/result.md)
Expand Down
55 changes: 55 additions & 0 deletions src/error/option_unwrap/question_mark.md
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));
}
```

0 comments on commit a72e9d2

Please sign in to comment.