Vin*_*ent 3 closures rust borrow-checker
我越来越
错误[E0373]:闭包可能比当前函数的寿命更长,但它借用了
row_nr当前函数所拥有的
我不希望这样,因为row_nr是 a u32,所以我希望它被复制而不是移动:
fn get_neighbours(values: &Vec<Vec<u32>>, row: usize, col: usize) -> Vec<u32> {
vec![
values.get(row - 1).and_then(|cols| cols.get(col)),
values.get(row).and_then(|cols| cols.get(col - 1)),
values.get(row).and_then(|cols| cols.get(col + 1)),
values.get(row + 1).and_then(|cols| cols.get(col)),
].into_iter().filter_map(|value_opt| value_opt.map(|value| *value)).collect()
}
fn get_points(values: Vec<Vec<u32>>) -> Vec<(u32, Vec<u32>)> {
values
.iter()
.enumerate()
.flat_map(|(row_nr, columns)| {
columns.iter().enumerate().map(|(column_nr, height)| {
let neighbours = get_neighbours(&values, row_nr, column_nr);
(*height, neighbours)
})
}).collect()
}
Run Code Online (Sandbox Code Playgroud)
完整错误消息:
--> src/lib.rs:16:44
|
16 | columns.iter().enumerate().map(|(column_nr, height)| {
| ^^^^^^^^^^^^^^^^^^^^^ may outlive borrowed value `row_nr`
17 | let neighbours = get_neighbours(&values, row_nr, column_nr);
| ------ `row_nr` is borrowed here
|
note: closure is returned here
--> src/lib.rs:16:13
|
16 | / columns.iter().enumerate().map(|(column_nr, height)| {
17 | | let neighbours = get_neighbours(&values, row_nr, column_nr);
18 | | (*height, neighbours)
19 | | })
| |______________^
help: to force the closure to take ownership of `row_nr` (and any other referenced variables), use the `move` keyword
|
16 | columns.iter().enumerate().map(move |(column_nr, height)| {
| ++++
Run Code Online (Sandbox Code Playgroud)
另请参阅Rust 游乐场。
现在,错误建议使用move,但这会成为问题,因为我只想传递对valuesVec 的引用(我认为它不应该比闭包更长久,因为从该 Vec 中get_neighbours获取u32s ,因此也应该进行复制,我思考?)。
我想我在这里误解了生命周期。如果您对我的误解有任何见解,我将不胜感激。我查看了几个相关的问题,但他们似乎要么使用 a 解决它move(如上所述,我认为我应该(能够)避免?),要么有多个借用检查器问题,这对我来说很困难了解哪些适用于我(例如这个答案)。
我没想到会这样,因为
row_nr是 au32,所以我希望它被复制而不是移动
假设它首先被移动,这个期望是正确的。在这种情况下,它不会被移动,而是被借用,因为默认情况下闭包会从其环境中借用值。要请求 a move,这u32确实会产生副本,您需要move显式使用关键字。
正如您发现的,当您只使用 时move,您也会移动values,这不会编译并且无论如何都不是您想要的。仅将一个值移动到闭包中的标准 Rust 习惯用法是使用并显式借用您不想move移动的捕获变量(在您的情况下)。例如,这样编译:values
.flat_map(|(row_nr, columns)| {
columns.iter().enumerate().map({
let values = &values;
move |(column_nr, height)| {
let neighbours = get_neighbours(values, row_nr, column_nr);
(*height, neighbours)
}
})
})
Run Code Online (Sandbox Code Playgroud)
至于为什么闭包可能比当前函数寿命更长的标题问题:请注意,错误消息中的“当前函数”指的是外部闭包,即传递给flat_map(). 由于内部闭包成为 所返回的迭代器的一部分map(),并且外部闭包立即返回该迭代器,因此内部闭包确实比“当前函数”活得更久,并且不能允许借用row_nr或columns。(但是借用values是完全没问题的,因为values这两次关闭的寿命都更长。)
| 归档时间: |
|
| 查看次数: |
1058 次 |
| 最近记录: |