简体   繁体   English

HashMap 编辑值和迭代器 Rust

[英]HashMap edit value and Iter Rust

hi i have a function like that and a HashMap and the probleme is i want to iter and edit the HashMap but i have too much erro with a clone the code compil but the value of the HashMap hi i have a function like that and a HashMap and the probleme is i want to iter and edit the HashMap but i have too much erro with a clone the code compil but the value of the 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);
                }
            };
        }
    }
}

here the link of the full code if you need/want to try Link如果您需要/想尝试链接,请在此处查看完整代码的链接

and the dependecies of cargo和货物的依赖

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

While you're cloning self.0 to coco , the following for loop you're consuming the HashMap .当您将self.0克隆到coco时,您正在使用以下 for 循环HashMap So while you're modifying x you're not actually affecting the key in coco , as you cannot mutate keys in a HashMap .因此,当您修改x时,您实际上并没有影响coco中的键,因为您不能改变HashMap中的键。

Instead wrap the body of you for loop in a map() and then collect() the result back into self.0 .而是将 for 循环的主体包裹在map()中,然后collect()将结果返回self.0

Also your += / -= for the keys are flipped.您的+= / -=键也被翻转。

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();
}

Alternatively, if you want to avoid cloning the whole HashMap up front, then you can use .iter() and clone() in map() .或者,如果您想避免预先克隆整个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<_, _>>();
}

or you could mem::replace() and extend() .或者你可以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)
    }));
}

Also, I highly suggest using rustfmt to keep your code nicely formatted, not to mention that your mix of English and non-English names can create confusion.另外,我强烈建议使用rustfmt来保持代码格式良好,更不用说英文和非英文名称的混合会造成混淆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM