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
// Both `name` and `first_char` are available here
191
+
println!("Running: {} (starts with '{}')", name, first_char);
192
+
}
193
+
Command::Run(name) => {
194
+
println!("Cannot run command: {}", name);
195
+
}
196
+
_=> {}
172
197
}
173
198
```
174
-
Here, `guard_expr` is evaluated and matched against `subpattern`. If the `if let` expression in the guard matches successfully, the arm's body is executed. Otherwise, pattern matching continues to the next arm.
199
+
Here, the guard condition `let Some(first_char) = name.chars().next()` is evaluated. If the `if let` expression successfully matches (i.e., the string has at least one character), the arm's body is executed with both `name` and `first_char` available. Otherwise, pattern matching continues to the next arm.
200
+
201
+
The key point is that the `if let` guard creates a new binding (`first_char`) that's only available if the guard succeeds, and this binding can be used alongside the original pattern bindings (`name`) in the arm's body.
175
202
176
203
r[expr.match.if.let.guard.behavior]
177
204
When the pattern matches successfully, the `if let` expression in the guard is evaluated:
178
205
* The guard proceeds if the inner pattern (`subpattern`) matches the result of `guard_expr`.
179
206
* Otherwise, the next arm is tested.
180
207
181
-
```rust,ignore
182
-
let value = Some(10);
183
-
184
-
let msg = match value {
185
-
Some(x) if let Some(y) = Some(x - 1) => format!("Matched inner value: {}", y),
186
-
_ => "No match".to_string(),
187
-
};
188
-
```
189
-
190
-
r[expr.match.if.let.guard.scope]
191
-
* The `if let` guard may refer to variables bound by the outer match pattern.
192
-
* New variables bound inside the `if let` guard (e.g., `y` in the example above) are available within the body of the match arm where the guard evaluates to `true`, but are not accessible in other arms or outside the match expression.
193
-
194
-
```rust,ignore
195
-
let opt = Some(42);
196
-
197
-
match opt {
198
-
Some(x) if let Some(y) = Some(x + 1) => {
199
-
// Both `x` and `y` are available in this arm,
200
-
// since the pattern matched and the guard evaluated to true.
201
-
println!("x = {}, y = {}", x, y);
202
-
}
203
-
_ => {
204
-
// `y` is not available here --- it was only bound inside the guard above.
205
-
// Uncommenting the line below will cause a compile-time error:
206
-
// println!("{}", y); // error: cannot find value `y` in this scope
208
+
```rust
209
+
# letvalue=Some(2)
210
+
# fnprocess(x:i32) ->Result<i32, String> {
211
+
# Ok(x+2)
212
+
# }
213
+
#
214
+
matchvalue {
215
+
Some(x) ifletOk(y) =process(x) => {
216
+
// ^ ^
217
+
// | |
218
+
// | +-- `y` bound in if-let guard
219
+
// +-- `x` bound in match arm pattern
220
+
//
221
+
// Both `x` and `y` are available here
222
+
println!("Processed {} into {}", x, y);
207
223
}
224
+
_=> {}
208
225
}
209
-
210
-
// Outside the match expression, neither `x` nor `y` are in scope.
211
226
```
212
227
213
-
* The outer pattern variables (`x`) follow the same borrowing behavior as in standard match guards (see below).
214
-
215
-
r[expr.match.if.let.guard.drop]
216
-
217
-
* Variables bound inside `if let` guards are dropped before evaluating subsequent match arms.
218
-
219
-
* Temporaries created during guard evaluation follow standard drop semantics and are cleaned up appropriately.
228
+
r[expr.match.if.let.guard.scope]
220
229
221
-
r[expr.match.if.let.guard.borrowing]
222
-
Variables bound by the outer pattern follow the same borrowing rules as standard match guards:
223
-
* A shared reference is taken to pattern variables before guard evaluation
224
-
* Values are moved or copied only when the guard succeeds
225
-
* Moving from outer pattern variables within the guard is restricted
230
+
For detailed information about variable scope and drop behavior, see the [scope and drop section].
0 commit comments