【发布时间】:2021-04-11 07:11:20
【问题描述】:
我找不到任何方法可以让我更新HashMap 的密钥。有get_key_value,但它返回的是不可变引用而不是可变引用。
【问题讨论】:
-
你不能,你必须删除并插入它。你想做什么?也许你还可以做点别的事情。
我找不到任何方法可以让我更新HashMap 的密钥。有get_key_value,但它返回的是不可变引用而不是可变引用。
【问题讨论】:
你一般1不能。来自HashMap 文档:
修改密钥的方式是逻辑错误,即密钥的哈希(由
Hash特征确定)或其相等性(由Eq特征确定)在其存在时发生变化地图。这通常只能通过Cell、RefCell、全局状态、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() 方法,一旦稳定,它就会提供对密钥的可变访问,但当然你仍然只能进行不修改密钥哈希的更改,也不修改它与其他密钥的比较键。