Rust 错误 [E0373]:闭包可能比当前函数长寿,但它借用了“iteration_index”
Rust error[E0373]: closure may outlive the current function, but it borrows `iteration_index`
我有两个 itertools::MinMaxResult
的向量。我需要遍历第一个向量,对于每个元素,遍历第二个向量,检查第一个向量的最小值是否等于第二个向量的任何元素的最大值,反之亦然。这是我尝试过的 MCVE:
use itertools::MinMaxResult; // itertools = "0.8.0"
use itertools::MinMaxResult::*;
pub fn mcve() -> Vec<(usize, usize)> {
// dummy variables to make the MCVE compile
let num_rows = 0;
let num_cols = 0;
let row_minmax: Vec<MinMaxResult<&u64>> = vec![];
let col_minmax: Vec<MinMaxResult<&u64>> = vec![];
// Problematic code:
(0..num_rows)
.flat_map(|row_index| {
(0_usize..num_cols).filter_map(|col_index| {
match (row_minmax[row_index], col_minmax[col_index]) {
(MinMax(a, _b), MinMax(_c, d)) if a == d =>
Some((row_index, col_index)),
(MinMax(_a, b), MinMax(c, _d)) if b == c =>
Some((row_index, col_index)),
_ => None,
}
})
})
.collect::<Vec<(usize, usize)>>()
}
Link to the Playground with full code
我收到以下错误:
error[E0373]: closure may outlive the current function, but it borrows `row_index`,
which is owned by the current function
--> src/main.rs:15:48
|
15 | (0_usize..num_cols).filter_map(|col_index| {
| ^^^^^^^^^^^ may outlive
borrowed value `row_index`
16 | match (row_minmax[row_index], col_minmax[col_index]) {
| --------- `row_index` is borrowed here
|
note: closure is returned here
--> src/main.rs:15:17
|
15 | / (0_usize..num_cols).filter_map(|col_index| {
16 | | match (row_minmax[row_index], col_minmax[col_index]) {
17 | | (MinMax(a, _b), MinMax(_c, d)) if a == d =>
Some((row_index, col_index)),
18 | | (MinMax(_a, b), MinMax(c, _d)) if b == c =>
Some((row_index, col_index)),
19 | | _ => None,
20 | | }
21 | | })
| |__________________^
help: to force the closure to take ownership of `row_index`
(and any other referenced variables), use the `move` keyword
|
15 | (0_usize..num_cols).filter_map(move |col_index| {
| ^^^^^^^^^^^^^^^^
如果我按照编译器的建议添加 move
,我会得到 两倍的 错误,所以这无济于事。我如何摆脱这个错误?
您的链接要点有一大堆典型的 "wrestling with the borrow-checker" 错误。以下是解决方法:
- 按照编译器的建议使用
move
,但要确保所有移动的值都实现 Copy
.
usize
类型的迭代索引已经实现 Copy
,因此这里无需执行任何操作。
- 向量是有问题的,所以只需获取它们的不可变引用,然后将不可变引用传递到闭包中。
- 您的
into_par_iter
导致了不相关的所有权问题。只需使用 par_iter
代替,然后您将迭代引用,而不是实际值,并且在迭代时不会破坏矩阵。
这里编译:
use itertools::MinMaxResult; // itertools = "0.8.0"
use itertools::MinMaxResult::*;
use itertools::Itertools;
use rayon::prelude::*; // rayon = "1.0.3"
pub fn find_saddle_points(input: &[Vec<u64>]) -> Vec<(usize, usize)> {
let flattened_matrix: Vec<(&u64)> = input.into_par_iter().flatten().collect();
if flattened_matrix.is_empty() {
vec![]
} else {
let num_rows = input.len();
let num_cols = input[0].len();
let row_minmax: Vec<MinMaxResult<&u64>> = input
.iter()
.map(|row| row.iter().minmax())
.collect::<Vec<MinMaxResult<&u64>>>();
let input_tranpose: Vec<Vec<u64>> = (0_usize..num_cols)
.into_par_iter()
.map(|col_index| {
(0_usize..num_rows)
.map(|row_index| input[row_index][col_index])
.collect::<Vec<u64>>()
})
.collect();
// don't take ownership!
// Use `par_iter` instead, then `col` will be a reference,
// and the borrow-checker is happy.
let col_minmax: Vec<MinMaxResult<&u64>> = input_tranpose
.par_iter()
.map(|col| col.iter().minmax())
.collect();
let rmm_ref = &row_minmax;
let cmm_ref = &col_minmax;
(0_usize..num_rows)
.flat_map(|row_index| {
(0_usize..num_cols).filter_map(move |col_index| {
match (rmm_ref[row_index], cmm_ref[col_index]) {
(MinMax(a, _b), MinMax(_c, d)) if a == d =>
Some((row_index, col_index)),
(MinMax(_a, b), MinMax(c, _d)) if b == c =>
Some((row_index, col_index)),
_ => None,
}
})
})
.collect::<Vec<(usize, usize)>>()
}
}
fn main(){}
我有两个 itertools::MinMaxResult
的向量。我需要遍历第一个向量,对于每个元素,遍历第二个向量,检查第一个向量的最小值是否等于第二个向量的任何元素的最大值,反之亦然。这是我尝试过的 MCVE:
use itertools::MinMaxResult; // itertools = "0.8.0"
use itertools::MinMaxResult::*;
pub fn mcve() -> Vec<(usize, usize)> {
// dummy variables to make the MCVE compile
let num_rows = 0;
let num_cols = 0;
let row_minmax: Vec<MinMaxResult<&u64>> = vec![];
let col_minmax: Vec<MinMaxResult<&u64>> = vec![];
// Problematic code:
(0..num_rows)
.flat_map(|row_index| {
(0_usize..num_cols).filter_map(|col_index| {
match (row_minmax[row_index], col_minmax[col_index]) {
(MinMax(a, _b), MinMax(_c, d)) if a == d =>
Some((row_index, col_index)),
(MinMax(_a, b), MinMax(c, _d)) if b == c =>
Some((row_index, col_index)),
_ => None,
}
})
})
.collect::<Vec<(usize, usize)>>()
}
Link to the Playground with full code
我收到以下错误:
error[E0373]: closure may outlive the current function, but it borrows `row_index`,
which is owned by the current function
--> src/main.rs:15:48
|
15 | (0_usize..num_cols).filter_map(|col_index| {
| ^^^^^^^^^^^ may outlive
borrowed value `row_index`
16 | match (row_minmax[row_index], col_minmax[col_index]) {
| --------- `row_index` is borrowed here
|
note: closure is returned here
--> src/main.rs:15:17
|
15 | / (0_usize..num_cols).filter_map(|col_index| {
16 | | match (row_minmax[row_index], col_minmax[col_index]) {
17 | | (MinMax(a, _b), MinMax(_c, d)) if a == d =>
Some((row_index, col_index)),
18 | | (MinMax(_a, b), MinMax(c, _d)) if b == c =>
Some((row_index, col_index)),
19 | | _ => None,
20 | | }
21 | | })
| |__________________^
help: to force the closure to take ownership of `row_index`
(and any other referenced variables), use the `move` keyword
|
15 | (0_usize..num_cols).filter_map(move |col_index| {
| ^^^^^^^^^^^^^^^^
如果我按照编译器的建议添加 move
,我会得到 两倍的 错误,所以这无济于事。我如何摆脱这个错误?
您的链接要点有一大堆典型的 "wrestling with the borrow-checker" 错误。以下是解决方法:
- 按照编译器的建议使用
move
,但要确保所有移动的值都实现Copy
. usize
类型的迭代索引已经实现Copy
,因此这里无需执行任何操作。- 向量是有问题的,所以只需获取它们的不可变引用,然后将不可变引用传递到闭包中。
- 您的
into_par_iter
导致了不相关的所有权问题。只需使用par_iter
代替,然后您将迭代引用,而不是实际值,并且在迭代时不会破坏矩阵。
这里编译:
use itertools::MinMaxResult; // itertools = "0.8.0"
use itertools::MinMaxResult::*;
use itertools::Itertools;
use rayon::prelude::*; // rayon = "1.0.3"
pub fn find_saddle_points(input: &[Vec<u64>]) -> Vec<(usize, usize)> {
let flattened_matrix: Vec<(&u64)> = input.into_par_iter().flatten().collect();
if flattened_matrix.is_empty() {
vec![]
} else {
let num_rows = input.len();
let num_cols = input[0].len();
let row_minmax: Vec<MinMaxResult<&u64>> = input
.iter()
.map(|row| row.iter().minmax())
.collect::<Vec<MinMaxResult<&u64>>>();
let input_tranpose: Vec<Vec<u64>> = (0_usize..num_cols)
.into_par_iter()
.map(|col_index| {
(0_usize..num_rows)
.map(|row_index| input[row_index][col_index])
.collect::<Vec<u64>>()
})
.collect();
// don't take ownership!
// Use `par_iter` instead, then `col` will be a reference,
// and the borrow-checker is happy.
let col_minmax: Vec<MinMaxResult<&u64>> = input_tranpose
.par_iter()
.map(|col| col.iter().minmax())
.collect();
let rmm_ref = &row_minmax;
let cmm_ref = &col_minmax;
(0_usize..num_rows)
.flat_map(|row_index| {
(0_usize..num_cols).filter_map(move |col_index| {
match (rmm_ref[row_index], cmm_ref[col_index]) {
(MinMax(a, _b), MinMax(_c, d)) if a == d =>
Some((row_index, col_index)),
(MinMax(_a, b), MinMax(c, _d)) if b == c =>
Some((row_index, col_index)),
_ => None,
}
})
})
.collect::<Vec<(usize, usize)>>()
}
}
fn main(){}