Rust 如何通过元组枚举变体过滤集合中的对应类型元素
解决方案
你需要用Rust内置的matches!宏来完成枚举变体的模式匹配判断,无需枚举所有子类型,有两种常用实现方案:
方案1:直接在filter中使用matches!宏
matches!可以直接判断值是否符合指定模式,不需要写完整的match表达式,修改你的filter代码如下即可:
.filter(|e| matches!(e.1, Item::Weapons(_)))
修改后的完整可运行代码:
use std::collections::BTreeMap; #[derive(PartialEq, Eq)] enum Item { Armor, Consumable, Weapons(WeaponTypes), } #[derive(PartialEq, Eq)] enum WeaponTypes { Axe, Bow, Sword, } fn main() { let mut stuff = BTreeMap::<&str, Item>::new(); stuff.insert("helmet of awesomeness", Item::Armor); stuff.insert("boots of the belligerent", Item::Armor); stuff.insert("potion of eternal life", Item::Consumable); stuff.insert("axe of the almighty", Item::Weapons(WeaponTypes::Axe)); stuff.insert("shortbow", Item::Weapons(WeaponTypes::Bow)); stuff.insert("sword of storm giants", Item::Weapons(WeaponTypes::Sword)); stuff .iter() .filter(|e| matches!(e.1, Item::Weapons(_))) .map(|e| e.0.to_string()) .for_each(|e| println!("'{}'", e)); }
运行后会输出所有武器类条目:
'axe of the almighty' 'shortbow' 'sword of storm giants'
方案2:给枚举添加类型判断辅助方法(更适合复用场景)
如果项目中多处需要判断物品类型,可以给Item枚举添加专用的判断方法,代码可读性和复用性更高:
impl Item { /// 判断是否为武器类物品 fn is_weapon(&self) -> bool { matches!(self, Self::Weapons(_)) } /// 判断是否为护甲类物品 fn is_armor(&self) -> bool { matches!(self, Self::Armor) } /// 判断是否为消耗品类物品 fn is_consumable(&self) -> bool { matches!(self, Self::Consumable) } }
之后filter逻辑可以简化为:
.filter(|e| e.1.is_weapon())
原代码报错原因说明
你之前的写法不生效是因为:
==是值相等比较运算符,右侧必须是完整的枚举实例,而Item::Weapons是枚举变体的构造函数,不是实例,不能直接用于比较- 模式匹配语法
Item::Weapons(_)不能直接写在==表达式中,需要通过matches!宏或者match表达式来使用
内容的提问来源于stack exchange,提问作者Jeremy Meadows
相关产品推荐
相关产品推荐

