【发布时间】:2022-01-16 05:58:58
【问题描述】:
所以我有一个使用字符串作为键的哈希图,值是我自己的用户结构。这只是他们的名字和职位
pub struct User {
name: String,
x: i32,
y: i32
}
现在我要做的是遍历名为 users 的 hashmap 并查看两个用户的位置是否彼此靠近,然后将它们分开。
for (key, userA) in self.users.iter_mut() {
for (key, userB) in self.users.iter_mut() {
// collision code would go in here
}
}
这会导致一个问题,因为用户随后被借用了两倍的可变用户。我想通过使用互斥体来解决这个问题,
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
}
}
并且代码可以编译,但是由于第二个循环,当我实际将用户添加到地图时,它会导致运行时错误,因为如果我注释掉该循环,则代码运行没有问题。关于如何以不同方式编写此内容的任何想法?
【问题讨论】:
-
为什么不进行不可变迭代(使用
.iter()而不是.iter_mut()),然后仅在需要更新时才进行可变借用? -
它抱怨它在循环开始时也被借用为不可变的,没有互斥锁。使用互斥锁在编译时很好,但据我了解,互斥锁会锁定循环中的第一个借用,这会破坏一切。
-
也许您可以使用嵌套的不可变迭代收集密钥对,然后根据收集的密钥对更新相应的值。
-
我现在看到了这个问题,这实际上有点棘手。最简单/性能最好的选项可能是
multi_mutcrate 之类的东西,但这似乎有点可疑。您可能最终需要将 hashmap 值包装在Cell或RefCell中并使用不可变迭代,除非 @Joe_Jingyu 的方法适合您的用例。 -
您是否尝试克隆用户 HashMap?
for (key, userA) in self.users.clone().iter_mut() {然后for (key, userA) in self.users.iter_mut() {```
标签: rust borrow-checker