首页 > 解决方案 > 当代码不是时,Rust 编译器抱怨在循环中使用移动值

问题描述

Rust 抱怨在循环中使用移动的值:

#[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
}

错误信息是:

error[E0382]: use of moved value
  --> src/lib.rs:14:18
   |
14 |             Some(a) => {
   |                  ^ value moved here, in previous iteration of loop
   |

当我阅读这段代码时,我看到它stage被移到a,然后可能被推到outs,然后再也不会使用。为什么这是编译器错误?

操场

有趣的是,以下替代方法有效:

            Some(a) if a != x => {
                    outs.push(a);
                    stage = Some(x);
            }
            _ => {}

标签: rust

解决方案


当你写

match stage {
    // ...
    Some(a) => {
        // ...
    }
}

无条件地将值移出stage. 块中的代码是否使用都a没有关系;Rust 所看到的stage只是现在无效,不能再次使用。

之所以

Some(a) if a != x => {
    outs.push(a);
    stage = Some(x);
}

有效是因为if在模式中包含 使其成为有条件的移动。只有在时a才会移出a != x,并且当这种情况发生时,stage总是会重新分配。


推荐阅读