如何复制而不是借用 i64 到 Rust 的闭包中?
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
编译它时,我收到以下错误消息:
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
类型,因此应该能够复制到捕获中,这正是我需要的吗?
我也试过内联 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
那么我怎样才能将我的整数复制到闭包中而不是借用它呢?
我尝试使用 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
所以我需要以某种方式让 rustc
只 move/copy 一些而不是另一个变量?
您可以使用 move
关键字将变量移动到闭包中。在这里你需要像这样更改闭包:
v.iter().map(move |n| // move is the keyword for moving variables into closure scope.
(n.clone(), id)
)
当您在 Rust 中创建闭包时,它会通过值或引用来捕获变量。两者混合是不可能的。默认情况下,它通过引用捕获,但是使用 move
关键字,它通过值捕获( 即 它将捕获的变量移动到闭包内)。
因此,在您的第一个代码中,您需要在闭包内移动 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))
});
}
那你问能不能"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
闭包中(这需要独占访问)。因此,您不能借用或移动 ids
,因为它已经被 FnMut
闭包借用了。最小复制:
fn main() {
let mut i = 0;
let mut closure = || {
i = 2;
|| {
println!("i = {}", i);
}
};
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(|n|
(n.clone(), id)
)
});
}
现在,当我用 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
但据我了解,id
属于 i64
类型,因此应该能够复制到捕获中,这正是我需要的吗?
我也试过内联 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
那么我怎样才能将我的整数复制到闭包中而不是借用它呢?
我尝试使用 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
所以我需要以某种方式让 rustc
只 move/copy 一些而不是另一个变量?
您可以使用 move
关键字将变量移动到闭包中。在这里你需要像这样更改闭包:
v.iter().map(move |n| // move is the keyword for moving variables into closure scope.
(n.clone(), id)
)
当您在 Rust 中创建闭包时,它会通过值或引用来捕获变量。两者混合是不可能的。默认情况下,它通过引用捕获,但是使用 move
关键字,它通过值捕获( 即 它将捕获的变量移动到闭包内)。
因此,在您的第一个代码中,您需要在闭包内移动 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))
});
}
那你问能不能"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
闭包中(这需要独占访问)。因此,您不能借用或移动 ids
,因为它已经被 FnMut
闭包借用了。最小复制:
fn main() {
let mut i = 0;
let mut closure = || {
i = 2;
|| {
println!("i = {}", i);
}
};
closure()();
}