【问题标题】:How can I remove the first element of a BTreeMap or HashMap that meets a condition? [duplicate]如何删除满足条件的 BTreeMap 或 HashMap 的第一个元素? [复制]
【发布时间】:2019-05-08 07:02:21
【问题描述】:

我想根据与值有关的某些属性从有序哈希图中删除 (key, value)

我写了以下最小示例:

use std::collections::BTreeMap;

pub fn remove_if42(map: &mut BTreeMap<String, u32>) -> Option<u32> {
    // Get the first element (minimum) from the ordered hash
    let (key, value) = map.iter_mut().next()?;

    if *value == 42 {
        map.remove(key);
    }
    Some(*value)
}

我可以读取值,但是当我要求删除密钥时,我得到一个借用错误:

error[E0499]: cannot borrow `*map` as mutable more than once at a time
 --> src/lib.rs:8:9
  |
5 |     let (key, value) = map.iter_mut().next()?;
  |                        --- first mutable borrow occurs here
...
8 |         map.remove(key);
  |         ^^^        --- first borrow later used here
  |         |
  |         second mutable borrow occurs here

【问题讨论】:

  • next_back() 不返回第一个元素,而是返回最后一个元素。
  • @Shepmaster Deer Shepmaster,你提到网络这是问题 32913368 的副本(removing-items-from-a-btreemap-or-btreeset-found-through-iteration)。确实,这两个问题是不同的。这与借用检查器有关,它仍然持有对密钥的引用,而没有涉及迭代器。在您链接的问题中,涉及迭代器并使其无效。而且,答案也不一样。 “可能的重复”回答“不,你不能这样做”。这个问题的答案是“是的,复制密钥”。问候,

标签: rust borrowing


【解决方案1】:

该错误是由于借用了键和值引起的。答案是在致电remove()之前复制它们:

use std::collections::BTreeMap;

pub fn remove_if42(map: &mut BTreeMap<String, u32>) -> Option<u32> {
    // Get the first element from the ordered hash
    let (key, value) = map.iter_mut().next_back()?;

    let key_cpy: String = key.to_string();
    let value_cpy = *value;
    if *value == 42 {
        map.remove(&key_cpy);
    }
    Some(value_cpy)
}

如果删除条目后不需要该值,则只需要密钥的副本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2020-07-14
    • 2015-07-09
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多