Rust is complaining of using a moved value in a loop:
#[derive(PartialEq, Eq)]
enum Animal {
Dog,
Cat,
}
fn dedup(animals: Vec<Animal>) -> Vec<Animal> {
let mut stage = None;
let mut outs = vec![];
for x in animals {
match stage {
None => stage = Some(x),
Some(a) => {
if a != x {
outs.push(a);
stage = Some(x);
}
}
}
}
if let Some(a) = stage {
outs.push(a);
}
outs
}
The error message is:
error[E0382]: use of moved value
--> src/lib.rs:14:18
|
14 | Some(a) => {
| ^ value moved here, in previous iteration of loop
|
When I read this code, I see that stage
is moved into a
, which is then possibly pushed to outs
, then never used again. Why is this a compiler error?
Interestingly, the following alternative works:
Some(a) if a != x => {
outs.push(a);
stage = Some(x);
}
_ => {}
When you write
match stage {
// ...
Some(a) => {
// ...
}
}
you are unconditionally moving the value out of stage
. It doesn't matter if the code in the block uses a
or not; all Rust sees is that the stage
is now invalidated, and cannot be used again.
The reason why
Some(a) if a != x => {
outs.push(a);
stage = Some(x);
}
works is because including the if
in the pattern makes it a conditional move. The a
is only moved out if a != x
, and when that happens, stage
is always reassigned.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.