Rust,在闭包内做一个闭包,避免 "closure may outlive the current function"
Rust, make a closure inside a closure avoiding "closure may outlive the current function"
我正在尝试编写一个函数来转换以下形式的数据结构:
input = [("a", [1,2,3]), ("b", [4,5,6])]
进入
output = [(a,1), (c,2) ..... (b,6)]
我的代码目前是这样的:
let foo=vec![('a', vec![1,2,3]), ('v', vec![2,3,4])];
let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( |b|(a.0, b))).flatten().collect();
println!("{:?}",baz);
我收到此错误:
error[E0373]: closure may outlive the current function, but it borrows `a`, which is owned by the current function
--> src/lib.rs:10:76
|
10 | let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( |b|(a.0, b))).flatten().collect();
| ^^^ - `a` is borrowed here
| |
| may outlive borrowed value `a`
|
note: closure is returned here
--> src/lib.rs:10:55
|
10 | let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( |b|(a.0, b))).flatten().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword
|
10 | let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( move |b|(a.0, b))).flatten().collect();
| ^^^^^^^^
error[E0382]: borrow of moved value: `a`
--> src/lib.rs:10:76
|
10 | let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( |b|(a.0, b))).flatten().collect();
| --- ^^^ - borrow occurs due to use in closure
| | |
| value moved here value borrowed here after partial move
|
= note: move occurs because `a.1` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
我认为这意味着 Rust 不知道如何复制我的 i32s 向量,所以认为它必须移动 vec,但不能这样做。
如何解决这个问题?为 vec 实现一个 Copy 方法,或者有更好的方法吗?
IntoIterator
消耗并产生值。由于 Vec
没有实现 Copy
,当你调用 a.1.into_iter()
时,它被移动了。您可以像这样克隆它:a.1.clone().into_iter()
此外,您想使用 move
关键字在闭包中获取 a
的所有权。
let baz: Vec<(char, i32)> = foo
.into_iter()
.map(|a| a.1.clone().into_iter().map(move |b| (a.0, b)))
.flatten()
.collect();
println!("{:?}", baz);
// [('a', 1), ('a', 2), ('a', 3), ('v', 2), ('v', 3), ('v', 4)]
当你调用a.1.into_iter()
时,a
被移动,不能再在内闭包中借用
最简单的解决方案是解构 a
,因此每个组件都可以 borrowed/moved 单独:
.map(|(c, v)| v.into_iter().map(move |b| (c, b)))
还要注意 move
关键字,这意味着 c
被移动到内部闭包中,因此它可以比外部闭包更有效。
我正在尝试编写一个函数来转换以下形式的数据结构:
input = [("a", [1,2,3]), ("b", [4,5,6])]
进入
output = [(a,1), (c,2) ..... (b,6)]
我的代码目前是这样的:
let foo=vec![('a', vec![1,2,3]), ('v', vec![2,3,4])];
let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( |b|(a.0, b))).flatten().collect();
println!("{:?}",baz);
我收到此错误:
error[E0373]: closure may outlive the current function, but it borrows `a`, which is owned by the current function
--> src/lib.rs:10:76
|
10 | let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( |b|(a.0, b))).flatten().collect();
| ^^^ - `a` is borrowed here
| |
| may outlive borrowed value `a`
|
note: closure is returned here
--> src/lib.rs:10:55
|
10 | let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( |b|(a.0, b))).flatten().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword
|
10 | let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( move |b|(a.0, b))).flatten().collect();
| ^^^^^^^^
error[E0382]: borrow of moved value: `a`
--> src/lib.rs:10:76
|
10 | let baz: Vec<(char,i32)> = foo.into_iter().map(|a|a.1.into_iter().map( |b|(a.0, b))).flatten().collect();
| --- ^^^ - borrow occurs due to use in closure
| | |
| value moved here value borrowed here after partial move
|
= note: move occurs because `a.1` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
我认为这意味着 Rust 不知道如何复制我的 i32s 向量,所以认为它必须移动 vec,但不能这样做。
如何解决这个问题?为 vec 实现一个 Copy 方法,或者有更好的方法吗?
IntoIterator
消耗并产生值。由于 Vec
没有实现 Copy
,当你调用 a.1.into_iter()
时,它被移动了。您可以像这样克隆它:a.1.clone().into_iter()
此外,您想使用 move
关键字在闭包中获取 a
的所有权。
let baz: Vec<(char, i32)> = foo
.into_iter()
.map(|a| a.1.clone().into_iter().map(move |b| (a.0, b)))
.flatten()
.collect();
println!("{:?}", baz);
// [('a', 1), ('a', 2), ('a', 3), ('v', 2), ('v', 3), ('v', 4)]
当你调用a.1.into_iter()
时,a
被移动,不能再在内闭包中借用
最简单的解决方案是解构 a
,因此每个组件都可以 borrowed/moved 单独:
.map(|(c, v)| v.into_iter().map(move |b| (c, b)))
还要注意 move
关键字,这意味着 c
被移动到内部闭包中,因此它可以比外部闭包更有效。