rust - 如何更新 HashMap 中的键?
问题描述
我找不到任何方法可以让我更新 a 的密钥HashMap
。有get_key_value
,但它返回一个不可变引用而不是可变引用。
解决方案
你一般1不能。从HashMap
文档中:
以这样一种方式修改键是一个逻辑错误,即键的哈希(由
Hash
trait 确定)或它的相等性(由Eq
trait 确定)在映射中发生变化。这通常只能通过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
(如Sven Marnach 所述)。
推荐阅读
- python - 在 Python 中的 asyncio 任务上拦截对 __await__ 的调用
- python - Pandas 数据框列匹配和分组依据
- python - 文本数据预处理的正确步骤是什么
- javascript - Node.js 上的 Minecraft 机器人
- java - Jersey 和 Springboot 应用程序抛出 java.lang.StackOverflowError
- verilog - 警告:实例化深度可能表示 ModelSim 中的递归
- php - php - 将选中的属性添加到匹配的下拉选项中
- kotlin - 如何通过 GSON 设置反序列化类的继承参数?
- rust - 如何解析包含简单列表和键值列表(关联数组)的 YAML
- java - 自定义jackson bean序列化器,可以根据兄弟属性的值动态忽略一些带注释的属性