为什么移动闭包不拥有变量的所有权?

时间:2019-05-10 11:29:06

标签: rust closures

The Rust Programming Language says

  

如果您要强制闭包对其在环境中使用的值拥有所有权,则可以在参数列表之前使用move关键字

我在代码中注意到的是,它不会拥有这些值的所有权。我的代码和给定示例之间的区别是:

  • 使用整数而不是Vec
  • 使x可变而不是不变

示例1: Rust编程语言

fn main() {
    let x = vec![1, 2, 3];

    let equal_to_x = move |z| z == x;

    println!("can't use x here: {:?}", x);

    let y = vec![1, 2, 3];

    assert!(equal_to_x(y));
}

示例2:我的代码

fn main() {
    let mut x = 1;

    let equal_to_x = move |z| z == x;

    println!("can use x here: {:?}", x);

    let y = 1;

    assert!(equal_to_x(y));
}
  1. 为什么示例2会编译但示例1不会编译?

  2. 为什么即使我在闭包前面显式写入xmove的所有权也不会移动?将x移到闭包后为何可以访问?

1 个答案:

答案 0 :(得分:2)

答案在第一个示例的错误消息中给出

error[E0382]: borrow of moved value: `x`
 --> src/main.rs:6:40
  |
2 |     let x = vec![1, 2, 3];
  |         - move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
3 | 
4 |     let equal_to_x = move |z| z == x;
  |                      --------      - variable moved due to use in closure
  |                      |
  |                      value moved into closure here
5 | 
6 |     println!("can't use x here: {:?}", x);
  |                                        ^ value borrowed here after move

“发生移动是因为x具有类型std::vec::Vec<i32>,它没有实现Copy特性”

这意味着,当类型实现Copy特征(如i32一样)时,将变量复制到闭包的范围内。