【问题标题】:Why doesn't a move closure take ownership of a variable?为什么移动闭包不获取变量的所有权?
【发布时间】:2019-05-10 11:29:05
【问题描述】:

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. A为什么x的所有权没有移动,即使我在闭包前明确写了move?为什么x 移入闭包后可以访问?

【问题讨论】:

  • 因为在您的示例 2 中,x 是可复制的,而在第一个中则不可复制。

标签: rust closures


【解决方案1】:

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

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&lt;i32&gt;,它没有实现 Copy 特征”

这意味着,当一个类型实现 Copy 特征时(就像 i32 所做的那样),move 会将变量复制到闭包的范围内。

【讨论】:

  • 感谢您的回答!如果我删除move 会有什么不同吗?它也会编译。
  • 对于副本类型,它根本没有任何区别。
  • @MariusRodi 是否使用move 确实会有所不同,即使对于Copy 的类型也是如此。如果没有move,变量将被借用,可能是可变的,而使用move,它将被复制到闭包中。在前一种情况下,只有一个具有单个值的变量被闭包借用,而在第二种情况下,有两个完全独立的变量——一个在闭包内,一个在封闭范围内。
猜你喜欢
  • 2020-05-04
  • 2020-11-17
  • 1970-01-01
  • 2020-11-04
  • 2019-12-14
  • 2019-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多