Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cannot bind by-move into a pattern guard

Tags:

How do I fix the problem of cannot bind by-move into a pattern guard [E0008] on s?

let res = match Some("hi".to_string()) {     Some(s) if s.len() == 0 => 1,     _ => 3 }; 

Is there anyway of changing it without putting the condition in the arm?

like image 774
Bilal Syed Hussain Avatar asked Apr 27 '15 01:04

Bilal Syed Hussain


1 Answers

In this case, you can bind by reference:

let res = match Some("hi".to_string()) {     Some(ref s) if s.len() == 0 => 1,     _ => 3 }; 

The general problem here is that binding by move must disallow further uses of the original variable, as moving out invalidates the data. If the guard is false, then the original variable needs to be used to match against the later patterns, which is illegal due to the move.

For example:

fn f(x: Option<String>) {     match x {         Some(a) if { drop(a); false } => println!("impossible"),         Some(b) => println!("whoops, {}", b),         None => println!("none"),     } } 

If x is Some, the internal String is moved out and deallocated when deciding if a arm should be taken, but that same String is immediately used again for the b arm once the a arm is rejected.

like image 157
huon Avatar answered Oct 24 '22 19:10

huon