Rust中无法从结果向量过滤出Ok值的技术问题排查
问题分析与解决
核心问题原因
你用data_set.iter().filter_map(Result::ok)报错的本质是迭代器类型不匹配:
data_set.iter()返回的是引用迭代器,迭代项类型是&Result<PerRequestData, E>(对每个Result的引用)Result::ok是一个self方法,它需要接收Result本身(所有权),而不是&Result。编译器提示的类型不匹配,核心就是参数类型不兼容。
两种解决方案
根据你是否需要保留原向量,分两种情况处理:
1. 保留原向量,获取PerRequestData的引用
如果不想消耗原data_set,需要先把&Result转换成Result<&PerRequestData, &E>,再调用ok():
let filtered_refs: Vec<&PerRequestData> = data_set.iter() .filter_map(|r| r.as_ref().ok()) .collect();
r.as_ref():将&Result<V,E>转换为Result<&V, &E>- 后续调用
ok()就能得到Option<&V>,符合filter_map的参数要求
2. 消耗原向量,获取PerRequestData的所有权
如果不需要保留原data_set,直接用into_iter()(所有权迭代器),这样迭代项就是Result<PerRequestData, E>本身,Result::ok可以直接作为参数传递:
let filtered_owned: Vec<PerRequestData> = data_set.into_iter() .filter_map(Result::ok) .collect();
关于flatten的用法
你提到的flatten实现需求也是可行的,因为Result<T,E>实现了IntoIterator trait:
Ok(t)会被转换成包含t的单元素迭代器Err(e)会被转换成空迭代器
所以用into_iter().flatten()可以直接过滤掉Err并收集Ok里的值:
// 同样会消耗原向量,得到Vec<PerRequestData> let filtered_flatten: Vec<PerRequestData> = data_set.into_iter() .flatten() .collect();
内容的提问来源于stack exchange,提问作者Nirmalya
相关产品推荐
相关产品推荐

