rust - 如何处理 HashMap 中的每个值并选择性地拒绝一些值?
问题描述
我想一个HashMap
一个地处理这些值,同时可能删除其中的一些。
例如,我想做一个等价的:
use std::collections::HashMap;
fn example() {
let mut to_process = HashMap::new();
to_process.insert(1, true);
loop {
// get an arbitrary element
let ans = to_process.iter().next().clone(); // get an item from the hash
match ans {
Some((k, v)) => {
if condition(&k,&v) {
to_process.remove(&k);
}
}
None => break, // work finished
}
}
}
但这无法编译:
error[E0502]: cannot borrow `to_process` as mutable because it is also borrowed as immutable
--> src/lib.rs:12:17
|
9 | let ans = to_process.iter().next().clone();
| ---------- immutable borrow occurs here
...
12 | to_process.remove(&k);
| ^^^^^^^^^^^------^^^^
| | |
| | immutable borrow later used by call
| mutable borrow occurs here
我知道我真的需要https://github.com/rust-lang/rust/issues/27804(这是 for HashSet
but forHashMap
相同),如果没有非可变和可变引用,我无法实施提供的解决方案仍然或使用不安全。
有没有我想念的简单方法?
解决方案
注意如果您需要HashMap
在处理过程中更改密钥或添加 kvps,请参阅@edwardw 的答案。除此以外 ...
使用HashMap::retain
. 您可以更改流程函数以返回bool
指示是否保留该键值对。例如
let mut to_process: HashMap<u32, String> = HashMap::new();
to_process.insert(1, "ok".to_string());
to_process.insert(2, "bad".to_string());
to_process.retain(process);
fn process(k: &u32, v: &mut String) -> bool {
// do stuff with k and v
v == "ok"
}