[英]How to copy instead of borrow an i64 into a closure in Rust?
I have the following minimal example of my code:我的代码有以下最小示例:
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)
)
});
}
Now, when I compile that with rustc
I get the following error message:现在,当我用
rustc
编译它时,我收到以下错误消息:
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
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
是i64
类型,因此应该能够被复制到捕获中,这正是我需要的?
I've also tried to inline the id
variable but to no avail:我也试过内联
id
变量,但无济于事:
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?那么如何将我的整数复制到闭包中而不是借用它呢?
I tried using move
, but rustc
doesn't like that either:我尝试使用
move
,但rustc
也不喜欢这样:
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
So I'd somehow need to get rustc
to only move/copy some but not the other variable?所以我不知何故需要让
rustc
只移动/复制一些而不是其他变量?
When you create a closure in Rust, it captures the variables either by value or by reference.当您在 Rust 中创建闭包时,它会通过值或引用来捕获变量。 A mix of both is impossible.
两者的混合是不可能的。 By default, it captures by reference, but with the
move
keyword, it captures by value ( ie it moves the captured variables inside the closure).默认情况下,它按引用捕获,但使用
move
关键字,它按值捕获(即它在闭包内移动捕获的变量)。
So, in your first code, you need to move id
inside the closure:因此,在您的第一个代码中,您需要将
id
移动到闭包中:
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))
});
}
Then you ask if you can "inline" ids
:然后你问你是否可以“内联”
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]))
});
}
You cannot put ids
at all in your inner closure, because you are already inside a FnMut
closure (that requires exclusive access).您根本不能将
ids
放在内部闭包中,因为您已经在FnMut
闭包中(需要独占访问)。 Thus, you cannot borrow or move ids
because it is already borrowed by the FnMut
closure.因此,您不能借用或移动
ids
因为它已经被FnMut
闭包借用了。 Minimal reproduction:最小复制:
fn main() {
let mut i = 0;
let mut closure = || {
i = 2;
|| {
println!("i = {}", i);
}
};
closure()();
}
You can move the variable into closure with move
keyword.您可以使用
move
关键字将变量移动到闭包中。 Here you need to change the closure like:在这里,您需要更改闭包,例如:
v.iter().map(move |n| // move is the keyword for moving variables into closure scope.
(n.clone(), id)
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.