@@ -215,22 +215,63 @@ match Some("hi".to_string()) {
215215The variable `s` has type `String`, and its use in the guard is as a variable of
216216type `String`. The guard code effectively executes in a separate scope to the
217217body 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.
221219
222- ```compile_fail
220+ The problem above can be solved by using the `ref` keyword.
221+
222+ ```
223223match Some("hi".to_string()) {
224- Some(s) if { drop(s); false } => (),
225- Some(s) => {}, // use s.
224+ Some(ref s) if s.len() == 0 => {},
226225 _ => {},
227226}
228227```
229228
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.
234275"## ,
235276
236277E0009 : r##"
0 commit comments