我正在编写一个函数来处理
Vec<Vec<i32>>
:
fn process_grid(grid: Vec<Vec<i32>>) -> Vec<i32> {
grid.iter()
.enumerate()
.flat_map(|(i, row)| {
row.iter()
.enumerate()
// closure may outlive the current function,
// but it borrows `i`, which is owned by the current function
.flat_map(|(j, val)| process(i, j, *val))
})
.collect()
}
fn process(i: usize, j: usize, val: i32) -> Option<i32> {
todo!()
}
完整的编译错误如下所示:
error[E0373]: closure may outlive the current function, but it borrows `i`, which is owned by the current function
--> src/main.rs:291:27
|
291 | .flat_map(|(j, val)| process(i, j, *val))
| ^^^^^^^^^^ - `i` is borrowed here
| |
| may outlive borrowed value `i`
|
note: closure is returned here
--> src/main.rs:289:13
|
289 | / row.iter()
290 | | .enumerate()
291 | | .flat_map(|(j, val)| process(i, j, *val))
| |_________________________________________________________^
help: to force the closure to take ownership of `i` (and any other referenced variables), use the `move` keyword
|
291 | .flat_map(move |(j, val)| process(i, j, *val))
| ++++
添加
move
关键字确实可以使事情正常工作,但它并没有明确说明为什么它不移动就无法编译。
封闭物
|(j, val)| process(i, j, *val)
怎么可能比其封闭的封闭物寿命更长:
|(i, row)| {
row.iter()
.enumerate()
// closure may outlive the current function,
// but it borrows `i`, which is owned by the current function
.flat_map(|(j, val)| process(i, j, *val))
}
也许在这里放置明确的生命周期会有帮助?
编译器选择仅使用相关闭包 references
i
,并且由于这是通过引用捕获的并且迭代器是惰性的,因此这将有效地尝试从外部 i
闭包返回对 flat_map
的引用,这是不允许的,因为 i
仅适用于该调用。
在这种情况下,通过添加 move
关键字来告诉编译器将
move捕获到闭包中就足够了,如下所示:
fn process_grid(grid: Vec<Vec<i32>>) -> Vec<i32> {
grid.iter()
.enumerate()
.flat_map(|(i, row)| {
row.iter()
.enumerate()
.flat_map(move |(j, val)| process(i, j, *val))
// ^^^^
})
.collect()
}