如何在Rust中复制而不是借用i64到闭包中? [英] How to copy instead of borrow an i64 into a closure in Rust?
问题描述
我有以下代码示例:
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屋!