简体   繁体   English

Rust - 如何迭代 hashmap 的元素并使其可变?

[英]Rust - How to iterate elements of a hashmap over themselves and have them be mutable?

So i have a hashmap that uses strings as keys and the values are my own struct for users.所以我有一个 hashmap 使用字符串作为键,值是我自己的用户结构。 Which is just their name and position这只是他们的名字和 position

pub struct User {
    name: String,
    x: i32,
    y: i32
}

Now what I want to do is iterate over the hashmap called users and see if two users position are close to each other, and then move them apart.现在我要做的是遍历 hashmap 调用的用户,看看两个用户 position 是否彼此靠近,然后将它们分开。

   for (key, userA) in self.users.iter_mut() {
      for (key, userB) in self.users.iter_mut() {
          //collision code would go in here
       }
    }

This causes an issue because users are then borrowed twice as mutable.这会导致一个问题,因为用户随后被借用了两倍的可变用户。 I thought of getting around this issue by using mutex,我想通过使用互斥锁来解决这个问题,

   for (key, userA) in self.users.lock().unwrap().iter_mut() {
      for (key, userB) in self.users.lock().unwrap().iter_mut() {
          //collision code would go in here
       }
    }

and the code compiles but it causes a runtime error later when I actually add an user to the map because of the second loop, since if I comment that loop out, the code runs with no issues.并且代码可以编译,但是当我实际上将用户添加到 map 时,它会导致运行时错误,因为第二个循环,因为如果我注释掉该循环,代码运行没有问题。 Any ideas on how I could write this differently?关于如何以不同方式编写此内容的任何想法?

You could do this in two stages.您可以分两个阶段执行此操作。 First you collect the collisions, and then resolve them.首先你收集碰撞,然后解决它们。 As an example:举个例子:

let mut collisions = Vec::new();
for (key_a, user_a) in self.users.iter() {
    for (key_b, user_b) in self.users.iter() {
        if key_a == key_b {
            continue;
        }

        if user_a.x == user_b.x && user_a.y == user_b.y {
            collisions.push((key_a, key_b));
        }
    }
}

for (key_a, key_b) in collisions {
    // Move users apart.
}

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

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