如何更新HashMap中的键?

너를 *_*속였다 0 key hashmap rust

我找不到任何允许我更新HashMap. 有get_key_value,但它返回一个不可变的引用而不是一个可变的引用。

She*_*ter 5

一般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);
    }
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:


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);
}
Run Code Online (Sandbox Code Playgroud)

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