如何在Rust中检查HashSet是否包含指定枚举变体(忽略关联值)
如何在Rust HashSet中检查枚举变体是否存在(忽略关联值)
原代码无法编译的原因是HashSet<SomeEnum>存储的是完整的枚举实例,而&One是变体构造函数,并非SomeEnum类型的有效值,因此contains方法无法识别。以下是几种可行的实现方案:
方案1:使用matches!宏遍历检查
这是最直接简洁的方式,适合偶尔进行此类检查的场景:
use std::collections::HashSet; #[derive(PartialEq, Hash, Eq)] pub enum SomeEnum { One(u32), Two(u32), } fn main() { use SomeEnum::*; let set = HashSet::from([One(123), Two(321)]); // 检查是否存在任意One变体实例 let has_one = set.iter().any(|item| matches!(item, One(_))); if has_one { // 执行逻辑 } }
matches!宏会快速匹配枚举变体,any方法只要找到一个符合条件的元素就返回true,无需遍历整个集合。
方案2:为枚举添加变体标识方法(类型安全版)
如果需要频繁检查或枚举变体较多,建议定义类型安全的变体标识,避免字符串比较的潜在错误:
use std::collections::HashSet; #[derive(PartialEq, Hash, Eq)] pub enum SomeEnum { One(u32), Two(u32), } // 定义枚举变体的标识类型 #[derive(PartialEq, Eq)] pub enum SomeEnumVariant { One, Two, } impl From<&SomeEnum> for SomeEnumVariant { fn from(item: &SomeEnum) -> Self { match item { SomeEnum::One(_) => Self::One, SomeEnum::Two(_) => Self::Two, } } } fn main() { use SomeEnum::*; let set = HashSet::from([One(123), Two(321)]); let has_one = set.iter().any(|item| SomeEnumVariant::from(item) == SomeEnumVariant::One); if has_one { // 执行逻辑 } }
方案3:预处理变体集合(高效多次查询)
如果需要对多个变体进行反复检查,提前将集合中的实例转换为变体标识并存储到新的HashSet中,后续查询可享受O(1)的效率:
use std::collections::HashSet; #[derive(PartialEq, Hash, Eq, Clone, Copy)] pub enum SomeEnumVariant { One, Two, } #[derive(PartialEq, Hash, Eq)] pub enum SomeEnum { One(u32), Two(u32), } impl From<&SomeEnum> for SomeEnumVariant { fn from(item: &SomeEnum) -> Self { match item { SomeEnum::One(_) => Self::One, SomeEnum::Two(_) => Self::Two, } } } fn main() { use SomeEnum::*; let set = HashSet::from([One(123), Two(321)]); // 预处理生成变体集合 let variant_set: HashSet<SomeEnumVariant> = set.iter().map(SomeEnumVariant::from).collect(); if variant_set.contains(&SomeEnumVariant::One) { // 执行逻辑 } }
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

