You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An `if` expression is a conditional branch in program control.
14
22
The syntax of an `if` expression is a condition operand, followed by a consequent block, any number of `else if` conditions and blocks, and an optional trailing `else` block.
An `if let` expression is semantically similar to an `if` expression but in place of a condition operand it expects the keyword `let` followed by a pattern, an `=` and a [scrutinee] operand.
52
51
If the value of the scrutinee matches the pattern, the corresponding block will execute.
@@ -90,27 +89,6 @@ let a = if let Some(1) = x {
90
89
assert_eq!(a, 3);
91
90
```
92
91
93
-
An `if let` expression is equivalent to a [`match` expression] as follows:
94
-
95
-
<!-- ignore: expansion example -->
96
-
```rust,ignore
97
-
if let PATS = EXPR {
98
-
/* body */
99
-
} else {
100
-
/*else */
101
-
}
102
-
```
103
-
104
-
is equivalent to
105
-
106
-
<!-- ignore: expansion example -->
107
-
```rust,ignore
108
-
match EXPR {
109
-
PATS => { /* body */ },
110
-
_ => { /* else */ }, // () if there is no else
111
-
}
112
-
```
113
-
114
92
Multiple patterns may be specified with the `|` operator. This has the same semantics as with `|` in `match` expressions:
115
93
116
94
```rust
@@ -126,30 +104,43 @@ if let E::X(n) | E::Y(n) = v {
126
104
```
127
105
128
106
The expression cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_].
129
-
Use of a lazy boolean operator is ambiguous with a planned feature change of the language (the implementation of if-let chains - see [eRFC 2947][_eRFCIfLetChain_]).
130
-
When lazy boolean operator expression is desired, this can be achieved by using parenthesis as below:
131
107
132
-
<!-- ignore: psuedo code -->
133
-
```rust,ignore
134
-
// Before...
135
-
if let PAT = EXPR && EXPR { .. }
108
+
## Chains of expressions
109
+
110
+
It is possible to chain multiple expressions into a single statement to avoid nested declarations.
136
111
137
-
// After...
138
-
if let PAT = ( EXPR && EXPR ) { .. }
112
+
```rust
113
+
fnsingle() {
114
+
letouter_opt=Some(Some(1i32));
115
+
116
+
ifletSome(inner_opt) =outer_opt
117
+
&&letSome(number) =inner_opt
118
+
&&number==1
119
+
{
120
+
println!("Peek a boo");
121
+
}
122
+
}
139
123
140
-
// Before...
141
-
if let PAT = EXPR || EXPR { .. }
124
+
fnnested() {
125
+
letouter_opt=Some(Some(1i32));
142
126
143
-
// After...
144
-
if let PAT = ( EXPR || EXPR ) { .. }
127
+
ifletSome(inner_opt) =outer_opt {
128
+
ifletSome(number) =inner_opt {
129
+
ifnumber==1 {
130
+
println!("Peek a boo");
131
+
}
132
+
}
133
+
}
134
+
}
145
135
```
146
136
137
+
The only remark is the fact that parenthesis (`if (let Some(a) = opt && (let Some(b) = a)) && b == 1`) and `||` operators (`if let A(x) = e1 || let B(x) = e2`) are not currently supported.
A `while let` loop is semantically similar to a `while` loop but in place of a condition expression it expects the keyword `let` followed by a pattern, an `=`, a [scrutinee] expression and a block expression.
70
76
If the value of the scrutinee matches the pattern, the loop body block executes then control returns to the pattern matching statement.
@@ -117,6 +123,26 @@ while let Some(v @ 1) | Some(v @ 2) = vals.pop() {
117
123
118
124
As is the case in [`if let` expressions], the scrutinee cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_].
119
125
126
+
### Chains of expressions
127
+
128
+
It is possible to chain multiple expressions into a single statement.
129
+
130
+
```rust
131
+
fnmain() {
132
+
letouter_opt=Some(Some(1i32));
133
+
134
+
whileletSome(inner_opt) =outer_opt
135
+
&&letSome(number) =inner_opt
136
+
&&number==1
137
+
{
138
+
println!("Peek a boo");
139
+
break;
140
+
}
141
+
}
142
+
```
143
+
144
+
The only remark is the fact that parenthesis (`while (let Some(a) = opt && (let Some(b) = a)) && b == 1`) and `||` operators (`while let A(x) = e1 || let B(x) = e2`) are not currently supported.
145
+
120
146
## Iterator loops
121
147
122
148
> **<sup>Syntax</sup>**\
@@ -148,35 +174,6 @@ for n in 1..11 {
148
174
assert_eq!(sum, 55);
149
175
```
150
176
151
-
A `for` loop is equivalent to a `loop` expression containing a [`match` expression] as follows:
152
-
153
-
<!-- ignore: expansion example -->
154
-
```rust,ignore
155
-
'label: for PATTERN in iter_expr {
156
-
/* loop body */
157
-
}
158
-
```
159
-
160
-
is equivalent to
161
-
162
-
<!-- ignore: expansion example -->
163
-
```rust,ignore
164
-
{
165
-
let result = match IntoIterator::into_iter(iter_expr) {
166
-
mut iter => 'label: loop {
167
-
let mut next;
168
-
match Iterator::next(&mut iter) {
169
-
Option::Some(val) => next = val,
170
-
Option::None => break,
171
-
};
172
-
let PATTERN = next;
173
-
let () = { /* loop body */ };
174
-
},
175
-
};
176
-
result
177
-
}
178
-
```
179
-
180
177
`IntoIterator`, `Iterator`, and `Option` are always the standard library items here, not whatever those names resolve to in the current scope.
181
178
The variable names `next`, `iter`, and `val` are for exposition only, they do not actually have names the user can type.
0 commit comments