将 for 循环转换为 Rust 中的迭代器

Nai*_*dra 1 iterator functional-programming compiler-errors traits rust

因此,我正在尝试构建自定义类型的向量的向量。我正在尝试为其实现默认值,并且通过 for 循环取得了成功。

let mut data: Vec<Vec<Cell>> = Vec::new();
    for _i in 0..63 {
        let mut row: Vec<Cell> = Vec::with_capacity(64);
        for _j in 0..63 {
            row.push(Cell::default())
        }
        data.push(row);
   }
Run Code Online (Sandbox Code Playgroud)

我觉得这段代码可以使用一些函数式风格和交互器,所以我决定这样做:

let data: Vec<Vec<Cell>> = Vec::with_capacity(64)
    .iter_mut()
    .map(|mut x: &mut Vec<Cell>| {
        x = Vec::with_capacity(64)
            .iter_mut()
            .map(|mut y: Cell| y = Cell::default())
            .collect()
        })
    .collect();
Run Code Online (Sandbox Code Playgroud)

这样,我收到如下错误:

error[E0631]: type mismatch in closure arguments
   --> src/types.rs:124:26
    |
124 |                         .map(|mut y: Cell| y = Cell::default())
    |                          ^^^ ------------- found signature defined here
    |                          |
    |                          expected due to this
    |
    = note: expected closure signature `fn(&mut _) -> _`
               found closure signature `fn(types::cell::Cell) -> _`
note: required by a bound in `map`
   --> /home/naitik/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:779:12
    |
779 |         F: FnMut(Self::Item) -> B,
    |            ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map`
Run Code Online (Sandbox Code Playgroud)

我不明白这里的问题。到底是什么?我能做什么来修复它?

isa*_*tfa 5

你误解了它的Vec::with_capacity工作原理。它实际上并没有将任何东西放入您可以迭代和分配的 vec 中。您想要映射Cell::default某些内容,然后将其收集到 vec 中。这并不重要,重要的是有 64 个,所以一个范围就可以了:

let data: Vec<Vec<Cell>> = (0..64)
        .map(|_| (0..64).map(|_| Cell::default()).collect())
        .collect();
Run Code Online (Sandbox Code Playgroud)

collect希望能够从范围的TrustedLenimpl 中自行计算出所需的容量,以避免不必要的重新分配。

然而,我怀疑这是否比程序方法更好。对我来说,这似乎不太清楚,也更难修改。只要坚持良好的 for 循环就是我的两分钱。

如果CellClone或者Copy你甚至可以这样做:

let data: Vec<Vec<Cell>> = vec![vec![Cell::default(); 64]; 64];
Run Code Online (Sandbox Code Playgroud)

以获得最大最小值。