Rust中如何对从dashmap::DashMap取出的元素执行模式匹配
问题原因
DashMap的get()方法返回值类型为Option<dashmap::mapref::one::Ref<'_, K, V>>,其中Ref是DashMap为了保障并发安全设计的智能指针类型(内部持有对应哈希槽位的读锁守卫),并非直接的Entity枚举值,因此无法直接匹配枚举变体。Ref实现了标准库的Deref<Target = Entity> trait,可以通过解引用操作获取内层的Entity引用。
解决方法
方法1:使用as_deref()转换后直接匹配
Option::as_deref()可以自动把Option<Ref<T>>转换为Option<&T>,转换后即可直接匹配枚举变体,写法最简洁:
match ENTITIES.get(&0).as_deref() { Some(Entity::Animal { name }) => { println!("found animal: {}", name); } _ => panic!("did not find animal"), }
方法2:先拿到Ref再解引用匹配
如果需要单独处理找不到实体的分支,可以先匹配到Ref再对其解引用后做二次匹配:
match ENTITIES.get(&0) { Some(entity_ref) => match *entity_ref { Entity::Animal { ref name } => println!("found animal: {}", name), Entity::Person { .. } => panic!("expected animal, got person"), }, None => panic!("did not find entity with id 0"), }
方法3:移出实体(需要所有权场景)
如果你不需要保留实体在DashMap中,可以用remove方法直接取出拥有所有权的实体,不需要处理Ref包装:
match ENTITIES.remove(&0) { Some((_, Entity::Animal { name })) => { println!("found animal: {}", name); } _ => panic!("did not find animal"), }
修正后完整可运行代码
use once_cell::sync::Lazy; use dashmap::DashMap; enum Entity { Person { name: String }, Animal { name: String }, } static ENTITIES: Lazy<DashMap<usize, Entity>> = Lazy::new(|| DashMap::new()); fn main() { ENTITIES.insert( 0, Entity::Animal { name: "pikachu".into(), }, ); ENTITIES.insert( 1, Entity::Person { name: "trainer mike".into(), }, ); // 使用as_deref的方案 match ENTITIES.get(&0).as_deref() { Some(Entity::Animal { name }) => { println!("found animal: {}", name); } _ => panic!("did not find animal"), } }
内容的提问来源于stack exchange,提问作者sno2
相关产品推荐
相关产品推荐

