HashMap 编辑值和 Iter Rust

HashMap edit value and Iter Rust

嗨,我有一个类似的函数和一个 HashMap,问题是我想迭代和编辑 HashMap,但是我有太多错误,克隆代码编译但 HashMap 的值

struct Piece(HashMap<(i32,i32), Couleur>);
fn press(&mut self, args: &Button) {
    let mut coco = self.0.clone();

    for (mut x, y) in coco {
        if let &Button::Keyboard(key) = args {
            match key {
                Key::Down => x.1 -= 1,
                Key::Left => x.0 += 1,
                Key::Right => x.0 -= 1,
                _ => {
                    println!("{:?}", x);
                }
            };
        }
    }
}

这里是完整代码的 link 如果你 need/want 试试 Link

以及货物的依赖项

[dependencies]
piston_window = "0.93.0"
rand = "0.6.5"

当您将 self.0 克隆到 coco 时,以下 for 循环会消耗 HashMap。因此,当您修改 x 时,您实际上并没有影响 coco 中的键,因为您无法改变 HashMap.

中的键

而是将 for 循环的主体包裹在 map() and then collect() 中,结果返回到 self.0

你的+=/-=键也被翻转了。

fn press(&mut self, args: &Button) {
    let coco = self.0.clone();
    self.0 = coco
        .into_iter()
        .map(|(mut x, y)| {
            if let &Button::Keyboard(key) = args {
                match key {
                    // Key::Up => x.1 -= 1,
                    Key::Down => x.1 += 1,
                    Key::Left => x.0 -= 1,
                    Key::Right => x.0 += 1,
                    _ => {
                        println!("{:?}", x);
                    }
                };
            }
            (x, y)
        })
        .collect();
}

或者,如果您想避免预先克隆整个 HashMap,则可以在 map() 中使用 .iter()clone()

fn press(&mut self, args: &Button) {
    self.0 = self
        .0
        .iter()
        .map(|(x, &y)| {
            let mut x = x.clone();
            if let &Button::Keyboard(key) = args {
                match key {
                    // Key::Up => x.1 -= 1,
                    Key::Down => x.1 += 1,
                    Key::Left => x.0 -= 1,
                    Key::Right => x.0 += 1,
                    _ => {
                        println!("{:?}", x);
                    }
                };
            }
            (x, y)
        })
        .collect::<HashMap<_, _>>();
}

或者你可以 mem::replace()extend().

fn press(&mut self, args: &Button) {
    let coco = std::mem::replace(&mut self.0, HashMap::new());
    self.0.extend(coco.into_iter().map(|(mut x, y)| {
        if let &Button::Keyboard(key) = args {
            match key {
                // Key::Up => x.1 -= 1,
                Key::Down => x.1 += 1,
                Key::Left => x.0 -= 1,
                Key::Right => x.0 += 1,
                _ => {
                    println!("{:?}", x);
                }
            };
        }
        (x, y)
    }));
}

此外,我强烈建议使用 rustfmt 来保持代码的格式良好,更不用说英文和非英文名称的混合会造成混淆。