Rust:如何用iter()和filter()过滤枚举向量提取关联结构体?
问题:过滤枚举向量中的特定变体并提取关联值
需求:从Vec<Item>中过滤出Item::G变体,提取内部的Group结构体以得到Vec<Group>,但代码运行时报错no field 0 on type &&Item。
错误原因
iter()返回的迭代器产生&Item类型的元素,filter闭包的参数是对该引用的二次引用(即&&Item),直接访问e.0是错误的,因为&&Item不存在名为0的字段。- 原代码中
matches!的使用方式错误,应该直接匹配枚举变体而非试图访问字段。
修正方案
1. 修正原过滤打印逻辑
如果只是想过滤出Item::G变体并打印,只需调整matches!的匹配目标:
#[derive(Debug, PartialEq, Eq)] enum Item { G(Group), S(MetaSegment) } #[derive(Debug, PartialEq, Eq)] struct Group {} #[derive(Debug, PartialEq, Eq)] struct MetaSegment {} fn main() { let mut stuff = Vec::<Item>::new(); stuff.push(Item::G(Group{})); stuff.push(Item::S(MetaSegment{})); stuff.push(Item::G(Group{})); // 修正filter条件:解引用二次引用后匹配变体 stuff .iter() .filter(|e| matches!(**e, Item::G(_))) .for_each(|e| println!("'{:#?}'", e)); }
2. 提取Vec<Group>(核心需求)
使用filter_map可以同时完成过滤和映射,一次遍历即可得到目标向量,分两种场景:
场景1:获取Group的引用(不转移所有权)
let groups: Vec<&Group> = stuff .iter() .filter_map(|item| match item { Item::G(group) => Some(group), Item::S(_) => None, }) .collect();
场景2:获取Group的所有权(消费原向量)
如果不需要保留原stuff向量,可以用into_iter()转移所有权,直接提取Group:
let groups: Vec<Group> = stuff .into_iter() .filter_map(|item| match item { Item::G(group) => Some(group), Item::S(_) => None, }) .collect();
内容的提问来源于stack exchange,提问作者Poulposaure
相关产品推荐
相关产品推荐

