无法在封闭内部借用Vec

时间:2017-07-07 23:12:57

标签: rust lifetime borrow-checker

我有null s的向量。我正在尝试构建一个名为Unit的{​​{1}}变量。在创建瓷砖的过程中,我需要知道它所知道的相邻瓷砖。

我有一个函数返回与另一个点相邻的点(Vec<Vec<Unit>>)的向量,我将其转换为迭代器,映射到它,并获得与该位置关联的实际单位在world中,如果它在那里,或当前行尚未提交到(usize, usize)

我需要访问world所占用的闭包中的那一行,但我还需要稍后访问它。

world

这是Rust Playground

我宁愿将mapfn adjacent((x, y): (usize, usize)) -> Vec<(usize, usize)> { vec![ (x+1, y), (x-1, y), (x, y+1), (x, y-1), ] } struct Unit { pub tiles: Vec<Tile>, } #[derive(Copy, Clone)] enum Tile { Floor, Wall, Empty } fn main() { let heightmap = vec![ vec![3, 3, 3, 3, 3, 3], vec![3, 1, 1, 1, 1, 3], vec![3, 1, 1, 1, 1, 3], vec![3, 1, 1, 1, 1, 3], vec![3, 1, 1, 1, 1, 3], vec![3, 1, 1, 1, 1, 3], vec![3, 3, 3, 3, 3, 3], ]; let (sx, sy) = (5, 5); let mut world: Vec<Vec<Unit>> = vec![]; for y in 0..sy { let mut line: Vec<Unit> = vec![]; for x in 0..sx { let mut tiles: Vec<Tile> = vec![]; let height = heightmap[y][x]; let adj = adjacent((x, y)) .iter() .map(|&(x, y)| { let list = if y > world.len() { vec![] } else if y == world.len() { line } else { world[y] }; if x >= list.len() { Tile::Empty } else { if height as usize >= list[x].tiles.len() { Tile::Empty } else { list[x].tiles[height as usize] } } }) .collect::<Vec<_>>(); for z in 0..(height as isize - 1) { tiles.push(Tile::Wall); } line.push(Unit { tiles: tiles, }); } world.push(line); } } 结合使用,但这会导致其他错误的临时值,而且无论如何都会更复杂,所以上面的代码可能不是最佳,就像我可以得到它一样简单,同时仍然重复错误。我发现Rust生成的很多错误都是因为我所做的并不是最好的方法,所以如果有一种更惯用的方法,我当然想知道。< / p>

我试图让unwrap_or克隆(导出getUnit)但Rust不会因某些原因让我,即使它只是由向量组成如果他们的成员是可复制的。

1 个答案:

答案 0 :(得分:1)

以下是您问题的一个较小示例:

fn main() {
    let mut line = vec![1];
    let something_to_iterate_over = vec![true, false, true];

    for _ in 0..2 {
        let _dummy: Vec<_> = something_to_iterate_over
            .iter()
            .map(|&value| {
                let maybe_moved_line = if value { vec![] } else { line };
                () // Don't care about the return value
            })
            .collect();

        line.push(2);
    }
}

错误消息的第一部分是:

error[E0382]: capture of moved value: `line`
 --> src/main.rs:9:67
  |
8 |             .map(|&value| {
  |                  -------- value moved (into closure) here
9 |                 let maybe_moved_line = if value { vec![] } else { line };
  |                                                                   ^^^^ value captured here after move
  |
  = note: move occurs because `line` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait

error[E0382]: use of moved value: `line`
  --> src/main.rs:14:9
   |
8  |             .map(|&value| {
   |                  -------- value moved (into closure) here
...
14 |         line.push(2);
   |         ^^^^ value used here after move
   |
   = note: move occurs because `line` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait

当错误消息试图传达时,代码在line调用后不再拥有变量map的所有权,因为所有权已转移到关闭。

代码试图向其他人提供单个Vec,同时保留自己,并且根本不是所有权如何运作。我不能把你的车给你,然后继续每天开车 - 这不是我的开车!

让代码编译的最小变化是停止尝试放弃唯一的line,而是根据需要克隆它:

  1. #[derive(Clone)]添加到Unit
  2. 在封闭内克隆lineworld[y]line.clone()world[y].clone()
  3. 执行此操作后,代码永远不会放弃line的所有权,因此可以在需要时进行克隆。