【问题标题】:How to update a key in a HashMap?如何更新 HashMap 中的键?
【发布时间】:2021-04-11 07:11:20
【问题描述】:

我找不到任何方法可以让我更新HashMap 的密钥。有get_key_value,但它返回的是不可变引用而不是可变引用。

【问题讨论】:

  • 你不能,你必须删除并插入它。你想做什么?也许你还可以做点别的事情。

标签: rust hashmap key


【解决方案1】:

一般1不能。来自HashMap 文档:

修改密钥的方式是逻辑错误,即密钥的哈希(由Hash 特征确定)或其相等性(由Eq 特征确定)在其存在时发生变化地图。这通常只能通过CellRefCell、全局状态、I/O 或不安全代码实现。

相反,删除该值并重新插入它:

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

fn rename_key<K, V>(h: &mut HashMap<K, V>, old_key: &K, new_key: K)
where
    K: Eq + Hash,
{
    if let Some(v) = h.remove(old_key) {
        h.insert(new_key, v);
    }
}

另见:


1 — 正如文档所述,可以修改它,只要您不更改密钥的散列或比较方式。这样做会导致HashMap 处于无效状态。

正确执行的示例(但仍然值得怀疑为什么):

use std::{
    cell::RefCell,
    collections::HashMap,
    hash::{Hash, Hasher},
    sync::Arc,
};

#[derive(Debug)]
struct Example<A, B>(A, B);

impl<A, B> PartialEq for Example<A, B>
where
    A: PartialEq,
{
    fn eq(&self, other: &Self) -> bool {
        self.0 == other.0
    }
}

impl<A, B> Eq for Example<A, B> where A: Eq {}

impl<A, B> Hash for Example<A, B>
where
    A: Hash,
{
    fn hash<H>(&self, h: &mut H)
    where
        H: Hasher,
    {
        self.0.hash(h)
    }
}

fn main() {
    let mut h = HashMap::new();
    let key = Arc::new(Example(0, RefCell::new(false)));

    h.insert(key.clone(), "alpha");
    dbg!(&h);

    *key.1.borrow_mut() = true;
    dbg!(&h);
}

您可以使用其他技术来获取对密钥的可变引用,例如不稳定的raw_entry_mut(如mentioned by Sven Marnach)。

【讨论】:

  • 还有一个不稳定的raw_entry_mut() 方法,一旦稳定,它就会提供对密钥的可变访问,但当然你仍然只能进行不修改密钥哈希的更改,也不修改它与其他密钥的比较键。
猜你喜欢
  • 1970-01-01
  • 2020-06-26
  • 2011-10-09
  • 1970-01-01
  • 2016-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多