Skip to content

Commit 995df09

Browse files
authored
Merge pull request #1640 from SebastianJL/add-let-else
Add documentation for let-else.
2 parents a4c007c + 658b708 commit 995df09

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
- [Guards](flow_control/match/guard.md)
6060
- [Binding](flow_control/match/binding.md)
6161
- [if let](flow_control/if_let.md)
62+
- [let-else](flow_control/let_else.md)
6263
- [while let](flow_control/while_let.md)
6364

6465
- [Functions](fn.md)

src/flow_control/let_else.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# let-else
2+
3+
4+
> 🛈 stable since: rust 1.65
5+
6+
7+
With `let`-`else`, a refutable pattern can match and bind variables
8+
in the surrounding scope like a normal `let`, or else diverge (e.g. `break`,
9+
`return`, `panic!`) when the pattern doesn't match.
10+
11+
```rust
12+
use std::str::FromStr;
13+
14+
fn get_count_item(s: &str) -> (u64, &str) {
15+
let mut it = s.split(' ');
16+
let (Some(count_str), Some(item)) = (it.next(), it.next()) else {
17+
panic!("Can't segment count item pair: '{s}'");
18+
};
19+
let Ok(count) = u64::from_str(count_str) else {
20+
panic!("Can't parse integer: '{count_str}'");
21+
};
22+
(count, item)
23+
}
24+
25+
assert_eq!(get_count_item("3 chairs"), (3, "chairs"));
26+
```
27+
28+
The scope of name bindings is the main thing that makes this different from
29+
`match` or `if let`-`else` expressions. You could previously approximate these
30+
patterns with an unfortunate bit of repetition and an outer `let`:
31+
32+
```rust
33+
# use std::str::FromStr;
34+
#
35+
# fn get_count_item(s: &str) -> (u64, &str) {
36+
# let mut it = s.split(' ');
37+
let (count_str, item) = match (it.next(), it.next()) {
38+
(Some(count_str), Some(item)) => (count_str, item),
39+
_ => panic!("Can't segment count item pair: '{s}'"),
40+
};
41+
let count = if let Ok(count) = u64::from_str(count_str) {
42+
count
43+
} else {
44+
panic!("Can't parse integer: '{count_str}'");
45+
};
46+
# (count, item)
47+
# }
48+
#
49+
# assert_eq!(get_count_item("3 chairs"), (3, "chairs"));
50+
```
51+
52+
### See also:
53+
54+
[option][option], [match][match], [if let][if_let] and the [let-else RFC][let_else_rfc].
55+
56+
57+
[match]: ./match.md
58+
[if_let]: ./if_let.md
59+
[let_else_rfc]: https://rust-lang.github.io/rfcs/3137-let-else.html
60+
[option]: ../std/option.md

0 commit comments

Comments
 (0)