如何在Rust中复制而不是借用i64到闭包中? [英] How to copy instead of borrow an i64 into a closure in Rust?

查看:205
本文介绍了如何在Rust中复制而不是借用i64到闭包中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码示例:

fn main()
{
    let names : Vec<Vec<String>> = vec![
        vec!["Foo1".to_string(), "Foo2".to_string()],
        vec!["Bar1".to_string(), "Bar2".to_string()]
    ];
    let ids : Vec<i64> = vec![10, 20];

    names.iter().enumerate().flat_map(|(i,v)| {
        let id : i64 = ids[i];
        v.iter().map(|n| 
            (n.clone(), id)
        )
    });
}

现在,当我使用 rustc进行编译时我收到以下错误消息:

Now, when I compile that with rustc I get the following error message:

error[E0597]: `id` does not live long enough
  --> main.rs:12:16
   |
11 |         v.iter().map(|n| 
   |                      --- capture occurs here
12 |             (n.clone(), id)
   |                         ^^ borrowed value does not live long enough
13 |         )
14 |     });
   |     -- borrowed value needs to live until here
   |     |
   |     borrowed value only lives until here

但据我了解, id 类型为 i64 ,因此应该能够将其复制到捕获中,这正是我所需要的吗?

But in my understanding, id is of type i64 and should therefore be able to be copied into the capture, with would be exactly what I need?

我也曾尝试内联 id 变量,但无济于事:

I've also tried to inline the id variable but to no avail:

error[E0597]: `i` does not live long enough
  --> main.rs:11:21
   |
10 |             v.iter().map(|n| 
   |                          --- capture occurs here
11 |                 (n.clone(), ids[i])
   |                                 ^ borrowed value does not live long enough
12 |             )
13 |         });
   |         -- borrowed value needs to live until here
   |         |
   |         borrowed value only lives until here

那么我如何才能将整数复制到闭包中而不是借用它呢?

So how can I copy my integer into the closure instead of borrowing it?

我尝试使用 move ,但 rustc 却没有 t可能是这样的:

I tried using move, but rustc doesn't like that either:

error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
  --> main.rs:10:17
   |
7  |         let ids : Vec<i64> = vec![10, 20];
   |             --- captured outer variable
...
10 |             v.iter().map(move |n| 
   |                          ^^^^^^^^ cannot move out of captured outer variable in an `FnMut` closure

所以我需要以某种方式获取 rustc 来仅移动/复制某些变量,而不移动其他变量?

So I'd somehow need to get rustc to only move/copy some but not the other variable?

推荐答案

在Rust中创建闭包时,它会通过值或引用来捕获变量。默认情况下,它通过引用捕获,但是使用 move 关键字,它按值捕获( ie 将捕获的变量移动到闭包内部)。

When you create a closure in Rust, it captures the variables either by value or by reference. A mix of both is impossible. By default, it captures by reference, but with the move keyword, it captures by value (i.e. it moves the captured variables inside the closure).

因此,在您的第一个代码中,需要将 id 移到闭包内:

So, in your first code, you need to move id inside the closure:

fn main() {
    let names: Vec<Vec<String>> = vec![
        vec!["Foo1".to_string(), "Foo2".to_string()],
        vec!["Bar1".to_string(), "Bar2".to_string()],
    ];
    let ids: Vec<i64> = vec![10, 20];

    names.iter().enumerate().flat_map(|(i, v)| {
        let id: i64 = ids[i];
        v.iter().map(move |n| (n.clone(), id))
    });
}

然后,您问是否可以内联 id

Then you ask if you can "inline" ids:

fn main() {
    let names: Vec<Vec<String>> = vec![
        vec!["Foo1".to_string(), "Foo2".to_string()],
        vec!["Bar1".to_string(), "Bar2".to_string()],
    ];
    let ids: Vec<i64> = vec![10, 20];

    names.iter().enumerate().flat_map(|(i, v)| {
        v.iter().map(|n| (n.clone(), ids[i]))
    });
}

您不能放置 ids 完全放在内部闭包中,因为您已经在 FnMut 闭包中(需要独占访问)。因此,您不能借用或移动 id ,因为 FnMut 闭包已经借用了它。最小复制:

You cannot put ids at all in your inner closure, because you are already inside a FnMut closure (that requires exclusive access). Thus, you cannot borrow or move ids because it is already borrowed by the FnMut closure. Minimal reproduction:

fn main() {
    let mut i = 0;

    let mut closure = || {
        i = 2;
        || {
            println!("i = {}", i);
        }
    };

    closure()();
}

这篇关于如何在Rust中复制而不是借用i64到闭包中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆