Reputation: 9214
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?
Upvotes: 22
Views: 5689
Reputation: 102096
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.
Upvotes: 34