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
174
+
println!("Running: {} (starts with '{}')", name, first_char);
175
+
}
176
+
Command::Run(name) => {
177
+
println!("Cannot run command: {}", name);
178
+
}
179
+
_=> {}
172
180
}
173
181
```
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.
182
+
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.
183
+
184
+
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
185
176
186
r[expr.match.if.let.guard.behavior]
177
187
When the pattern matches successfully, the `if let` expression in the guard is evaluated:
178
188
* The guard proceeds if the inner pattern (`subpattern`) matches the result of `guard_expr`.
179
189
* Otherwise, the next arm is tested.
180
190
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
191
+
```rust
192
+
# letvalue=Some(2)
193
+
# fnprocess(x:i32) ->Result<i32, String> {
194
+
# Ok(x+2)
195
+
# }
196
+
#
197
+
matchvalue {
198
+
Some(x) ifletOk(y) =process(x) => {
199
+
// ^ ^
200
+
// | |
201
+
// | +-- `y` bound in if-let guard
202
+
// +-- `x` bound in match arm pattern
203
+
//
204
+
// Both `x` and `y` are available here
205
+
println!("Processed {} into {}", x, y);
207
206
}
207
+
_=> {}
208
208
}
209
-
210
-
// Outside the match expression, neither `x` nor `y` are in scope.
211
209
```
212
210
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.
211
+
r[expr.match.if.let.guard.scope]
220
212
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
213
+
For detailed information about variable scope and drop behavior, see the [scope and drop section].
0 commit comments