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

Mar*_*odi 1 closures rust

Rust 编程语言

如果你想强制闭包取得它在环境中使用的值的所有权,你可以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));
}
Run Code Online (Sandbox Code Playgroud)

示例 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));
}
Run Code Online (Sandbox Code Playgroud)
  1. 为什么示例 2 可以编译,但示例 1 却不能?

  2. xA为什么即使我明确写 move在闭包前面,所有权也没有移动?为什么x移入封闭后可以访问?

hel*_*low 5

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

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
Run Code Online (Sandbox Code Playgroud)

“发生移动是因为x具有 type std::vec::Vec<i32>,但它没有实现该Copy特征”

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

  • @MariusRodi 是否使用“move”确实会有所不同,即使对于“Copy”类型也是如此。如果没有“move”,变量将被借用,可能是可变的,而使用“move”,变量将被复制到闭包中。在前一种情况下,只有一个具有单个值的变量被闭包借用,而在第二种情况下,有两个完全独立的变量——一个在闭包内,一个在封闭范围内。 (3认同)

归档时间:

查看次数:

1465 次

最近记录:

6 年,6 月 前