当键不可克隆时,将满足谓词的单个条目移出HashMap

时间:2019-03-28 03:44:02

标签: rust hashmap borrow-checker

我正在编写一个与HashMap配合使用的函数,并且该函数在函数的各个点上都想检查映射中的任何值是否满足条件,并且是否确实返回了一个键符合条件的条目。

到目前为止,我尝试首先遍历引用以检查我的状况,然后使用remove_entry获取密钥的拥有副本而不是借用:

use std::{collections::HashMap, hash::Hash};

fn remove_first_odd<K: Hash + Eq>(map: &mut HashMap<K, u64>) -> Option<K> {
    let maybe_entry = map.iter().find(|(_, &value)| value & 1 == 1);

    match maybe_entry {
        Some((key_ref, _value_ref)) => {
            let (key_owned, _value_owned) = map.remove_entry(key_ref).unwrap();
            Some(key_owned)
        }
        None => None,
    }
}

但这无法通过借阅检查,因为在我仍然持有对其中一个键的引用的同时,我无法对地图进行变异:

error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
 --> src/lib.rs:8:45
  |
4 |     let maybe_entry = map.iter().find(|(_, &value)| value & 1 == 1);
  |                       --- immutable borrow occurs here
...
8 |             let (key_owned, _value_owned) = map.remove_entry(key_ref).unwrap();
  |                                             ^^^^------------^^^^^^^^^
  |                                             |   |
  |                                             |   immutable borrow later used by call
  |                                             mutable borrow occurs here

我相信这是可行的,因为只要remove_entry仅在突变之前而不是之后取消引用我的密钥,这应该是正确的。

那么有安全的API可以执行此操作吗?如果没有,可以创建一个吗?

请注意:

  • 我不能克隆我的密钥,因为它们是通用的,没有克隆绑定
  • 我不能用HashMap之类的东西来消费.into_iter()
  • 我只需要删除一个条目,而不是所有匹配的条目

0 个答案:

没有答案