@@ -215,22 +215,63 @@ match Some("hi".to_string()) {
215
215
The variable `s` has type `String`, and its use in the guard is as a variable of
216
216
type `String`. The guard code effectively executes in a separate scope to the
217
217
body of the arm, so the value would be moved into this anonymous scope and
218
- therefore become unavailable in the body of the arm. Although this example seems
219
- innocuous, the problem is most clear when considering functions that take their
220
- argument by value.
218
+ therefore becomes unavailable in the body of the arm.
221
219
222
- ```compile_fail
220
+ The problem above can be solved by using the `ref` keyword.
221
+
222
+ ```
223
223
match Some("hi".to_string()) {
224
- Some(s) if { drop(s); false } => (),
225
- Some(s) => {}, // use s.
224
+ Some(ref s) if s.len() == 0 => {},
226
225
_ => {},
227
226
}
228
227
```
229
228
230
- The value would be dropped in the guard then become unavailable not only in the
231
- body of that arm but also in all subsequent arms! The solution is to bind by
232
- reference when using guards or refactor the entire expression, perhaps by
233
- putting the condition inside the body of the arm.
229
+ Though this example seems innocuous and easy to solve, the problem becomes clear
230
+ when it encounters functions which consume the value:
231
+
232
+ ```compile_fail
233
+ struct A{}
234
+
235
+ impl A {
236
+ fn consume(self) -> usize {
237
+ 0
238
+ }
239
+ }
240
+
241
+ fn main() {
242
+ let a = Some(A{});
243
+ match a {
244
+ Some(y) if y.consume() > 0 => {}
245
+ _ => {}
246
+ }
247
+ }
248
+ ```
249
+
250
+ In this situation, even the `ref` keyword cannot solve it, since borrowed
251
+ content cannot be moved. This problem cannot be solved generally. If the value
252
+ can be cloned, here is a not-so-specific solution:
253
+
254
+ ```
255
+ #[derive(Clone)]
256
+ struct A{}
257
+
258
+ impl A {
259
+ fn consume(self) -> usize {
260
+ 0
261
+ }
262
+ }
263
+
264
+ fn main() {
265
+ let a = Some(A{});
266
+ match a{
267
+ Some(ref y) if y.clone().consume() > 0 => {}
268
+ _ => {}
269
+ }
270
+ }
271
+ ```
272
+
273
+ If the value will be consumed in the pattern guard, using its clone will not
274
+ move its ownership, so the code works.
234
275
"## ,
235
276
236
277
E0009 : r##"
0 commit comments