Rust中如何从Option<Ref<K,V>>提取&V?泛型哈希表类型兼容问题
解决HashMap/DashMap泛型哈希表的get/get_mut类型兼容问题
核心问题在于std::collections::HashMap和dashmap::DashMap的get/get_mut返回类型不统一:前者直接返回引用,后者返回带锁的包装类型。我们可以通过抽象统一接口的方式抹平差异,具体实现如下:
方案1:定义通用Trait抽象底层存储
先定义一个GenericMap trait,把两种哈希表的核心方法抽象出来,通过关联类型统一返回值的行为(要求返回类型实现Deref/DerefMut):
use std::ops::{Deref, DerefMut}; // 抽象通用哈希表行为 pub trait GenericMap<K, V> { // 只读引用的关联类型,需实现Deref指向V type GetRef<'a>: Deref<Target = V> where Self: 'a, K: 'a, V: 'a; // 可变引用的关联类型,需实现DerefMut指向V type GetMutRef<'a>: DerefMut<Target = V> where Self: 'a, K: 'a, V: 'a; fn get(&self, key: &K) -> Option<Self::GetRef<'_>>; fn get_mut(&mut self, key: &K) -> Option<Self::GetMutRef<'_>>; } // 为std HashMap实现Trait impl<K, V> GenericMap<K, V> for std::collections::HashMap<K, V> where K: std::cmp::Eq + std::hash::Hash, { type GetRef<'a> = &'a V where Self: 'a, K: 'a, V: 'a; type GetMutRef<'a> = &'a mut V where Self: 'a, K: 'a, V: 'a; fn get(&self, key: &K) -> Option<Self::GetRef<'_>> { std::collections::HashMap::get(self, key) } fn get_mut(&mut self, key: &K) -> Option<Self::GetMutRef<'_>> { std::collections::HashMap::get_mut(self, key) } } // 为DashMap实现Trait impl<K, V> GenericMap<K, V> for dashmap::DashMap<K, V> where K: std::cmp::Eq + std::hash::Hash + Clone, { type GetRef<'a> = dashmap::mapref::one::Ref<'a, K, V> where Self: 'a, K: 'a, V: 'a; type GetMutRef<'a> = dashmap::mapref::one::RefMut<'a, K, V> where Self: 'a, K: 'a, V: 'a; fn get(&self, key: &K) -> Option<Self::GetRef<'_>> { dashmap::DashMap::get(self, key) } fn get_mut(&mut self, key: &K) -> Option<Self::GetMutRef<'_>> { dashmap::DashMap::get_mut(self, key) } }
方案2:基于Trait构建泛型哈希表
用上面的GenericMap trait约束你的泛型结构体,即可实现统一的方法调用:
pub struct MyHashMap<K, V, M: GenericMap<K, V>> { inner: M, } impl<K, V, M: GenericMap<K, V>> MyHashMap<K, V, M> { // 构造函数 pub fn new(inner: M) -> Self { Self { inner } } // 统一的get方法,返回实现Deref的类型 pub fn get(&self, key: &K) -> Option<impl Deref<Target = V> + '_> { self.inner.get(key) } // 统一的get_mut方法,返回实现DerefMut的类型 pub fn get_mut(&mut self, key: &K) -> Option<impl DerefMut<Target = V> + '_> { self.inner.get_mut(key) } // 可选:直接返回&V/&mut V的辅助方法,简化调用 pub fn get_value(&self, key: &K) -> Option<&V> { self.get(key).map(|r| r.deref()) } pub fn get_value_mut(&mut self, key: &K) -> Option<&mut V> { self.get_mut(key).map(|r| r.deref_mut()) } }
使用示例
无论底层是HashMap还是DashMap,调用方式完全一致:
// 用std HashMap初始化 let mut std_map = std::collections::HashMap::new(); std_map.insert(1, "hello"); let mut my_std_map = MyHashMap::new(std_map); // 两种获取值的方式都可行 if let Some(ref_val) = my_std_map.get(&1) { println!("{}", *ref_val); // 输出hello } if let Some(val) = my_std_map.get_value(&1) { println!("{}", val); // 输出hello } // 用DashMap初始化 let mut dash_map = dashmap::DashMap::new(); dash_map.insert(1, "world"); let mut my_dash_map = MyHashMap::new(dash_map); if let Some(ref_val) = my_dash_map.get(&1) { println!("{}", *ref_val); // 输出world }
内容的提问来源于stack exchange,提问作者user2066671
相关产品推荐
相关产品推荐

