Skip to content

Commit a72e9d2

Browse files
authored
Merge pull request #1250 from adamchalmers/option-question-mark
Fix #1110: add examples of ? and Option
2 parents 1626088 + e9464a2 commit a72e9d2

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
- [Error handling](error.md)
151151
- [`panic`](error/panic.md)
152152
- [`Option` & `unwrap`](error/option_unwrap.md)
153+
- [Unpacking options with ?](error/option_unwrap/question_mark.md)
153154
- [Combinators: `map`](error/option_unwrap/map.md)
154155
- [Combinators: `and_then`](error/option_unwrap/and_then.md)
155156
- [`Result`](error/result.md)
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Unpacking options with ?
2+
3+
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`.
4+
5+
```rust,editable
6+
fn next_birthday(current_age: Option<u8>) -> Option<String> {
7+
// If `current_age` is None, this returns None.
8+
// If `current_age` is Some, the inner u8 gets assigned to `next_age`
9+
let next_age: u8 = current_age?;
10+
Some(format!("Next year I will be {}", next_age))
11+
}
12+
```
13+
14+
You can chain many ?s together to make your code much more readable.
15+
16+
```rust,editable
17+
struct Person {
18+
job: Option<Job>,
19+
}
20+
21+
#[derive(Clone, Copy)]
22+
struct Job {
23+
phone_number: Option<PhoneNumber>,
24+
}
25+
26+
#[derive(Clone, Copy)]
27+
struct PhoneNumber {
28+
area_code: Option<u8>,
29+
number: u32,
30+
}
31+
32+
impl Person {
33+
34+
// Gets the area code of the phone number of the person's job, if it exists.
35+
fn work_phone_area_code(&self) -> Option<u8> {
36+
// This would need many nested `match` statements without the ? operator.
37+
// It would take a lot more code - try writing it yourself and see which
38+
// is easier.
39+
self.job?.phone_number?.area_code
40+
}
41+
}
42+
43+
fn main() {
44+
let p = Person {
45+
job: Some(Job {
46+
phone_number: Some(PhoneNumber {
47+
area_code: Some(61),
48+
number: 439222222,
49+
}),
50+
}),
51+
};
52+
53+
assert_eq!(p.work_phone_area_code(), Some(61));
54+
}
55+
```

0 commit comments

Comments
 (0)