如何修复 "Closure may outlive the current function"
How to fix "Closure may outlive the current function"
我有这个代码:
pub fn find_saddle_points(input: &[Vec<u64>]) -> Vec<(usize, usize)> {
let mut row_max: Vec<HashSet<usize>> = vec![HashSet::new(); input.len()];
let mut col_min: Vec<HashSet<usize>> = vec![HashSet::new(); input[0].len()];
...
row_max.iter().enumerate()
.flat_map(|(row, cols)| {
cols.iter()
.filter(|c| col_min[**c].contains(&row))
.map(|c| (row, *c))
})
.collect()
}
编译失败。
error[E0373]: closure may outlive the current function, but it borrows `row`, which is owned by the current function
--> src/lib.rs:48:21
|
48 | .filter(|c| col_min[**c].contains(&row))
| ^^^ --- `row` is borrowed here
| |
| may outlive borrowed value `row`
|
note: closure is returned here
--> src/lib.rs:47:9
|
47 | / cols.iter()
48 | | .filter(|c| col_min[**c].contains(&row))
49 | | .map(|c| (row, *c))
| |_______________________________^
help: to force the closure to take ownership of `row` (and any other referenced variables), use the `move` keyword
|
48 | .filter(move |c| col_min[**c].contains(&row))
| ++++
error[E0373]: closure may outlive the current function, but it borrows `row`, which is owned by the current function
--> src/lib.rs:49:18
|
49 | .map(|c| (row, *c))
| ^^^ --- `row` is borrowed here
| |
| may outlive borrowed value `row`
|
note: closure is returned here
--> src/lib.rs:47:9
|
47 | / cols.iter()
48 | | .filter(|c| col_min[**c].contains(&row))
49 | | .map(|c| (row, *c))
| |_______________________________^
help: to force the closure to take ownership of `row` (and any other referenced variables), use the `move` keyword
|
49 | .map(move |c| (row, *c))
| ++++
我可以在 map
中使用 move
,因为没有人在它后面使用 row
,但我不能在 filter
中使用 move
因为 col_min
有类型 Vec<HashSet<usize>>
,它没有实现 Copy
特征。如何解决这个问题?
要在 move
闭包中通过引用捕获某些内容,请在闭包外部创建一个引用,然后在闭包中使用该引用;引用将被移动到闭包中,而不是它引用的值。
row_max.iter().enumerate()
.flat_map(|(row, cols)| {
// Shadow col_min with a reference to the outer variable. The closure
// will capture this reference instead of the col_min value above.
let col_min = &col_min;
cols.iter()
.filter(move |c| col_min[**c].contains(&row))
.map(move |c| (row, *c))
})
.collect()
我有这个代码:
pub fn find_saddle_points(input: &[Vec<u64>]) -> Vec<(usize, usize)> {
let mut row_max: Vec<HashSet<usize>> = vec![HashSet::new(); input.len()];
let mut col_min: Vec<HashSet<usize>> = vec![HashSet::new(); input[0].len()];
...
row_max.iter().enumerate()
.flat_map(|(row, cols)| {
cols.iter()
.filter(|c| col_min[**c].contains(&row))
.map(|c| (row, *c))
})
.collect()
}
编译失败。
error[E0373]: closure may outlive the current function, but it borrows `row`, which is owned by the current function
--> src/lib.rs:48:21
|
48 | .filter(|c| col_min[**c].contains(&row))
| ^^^ --- `row` is borrowed here
| |
| may outlive borrowed value `row`
|
note: closure is returned here
--> src/lib.rs:47:9
|
47 | / cols.iter()
48 | | .filter(|c| col_min[**c].contains(&row))
49 | | .map(|c| (row, *c))
| |_______________________________^
help: to force the closure to take ownership of `row` (and any other referenced variables), use the `move` keyword
|
48 | .filter(move |c| col_min[**c].contains(&row))
| ++++
error[E0373]: closure may outlive the current function, but it borrows `row`, which is owned by the current function
--> src/lib.rs:49:18
|
49 | .map(|c| (row, *c))
| ^^^ --- `row` is borrowed here
| |
| may outlive borrowed value `row`
|
note: closure is returned here
--> src/lib.rs:47:9
|
47 | / cols.iter()
48 | | .filter(|c| col_min[**c].contains(&row))
49 | | .map(|c| (row, *c))
| |_______________________________^
help: to force the closure to take ownership of `row` (and any other referenced variables), use the `move` keyword
|
49 | .map(move |c| (row, *c))
| ++++
我可以在 map
中使用 move
,因为没有人在它后面使用 row
,但我不能在 filter
中使用 move
因为 col_min
有类型 Vec<HashSet<usize>>
,它没有实现 Copy
特征。如何解决这个问题?
要在 move
闭包中通过引用捕获某些内容,请在闭包外部创建一个引用,然后在闭包中使用该引用;引用将被移动到闭包中,而不是它引用的值。
row_max.iter().enumerate()
.flat_map(|(row, cols)| {
// Shadow col_min with a reference to the outer variable. The closure
// will capture this reference instead of the col_min value above.
let col_min = &col_min;
cols.iter()
.filter(move |c| col_min[**c].contains(&row))
.map(move |c| (row, *c))
})
.collect()