如何更简洁地将Vec<Result<Option<T>, E>>转换为Result<Vec<T>, E>
优化Vec<Result<Option, E>>到Result<Vec, E>的迭代器实现
你可以利用Rust标准库中Result::transpose()方法结合迭代器的filter_map()来大幅简化代码,同时保持第一段代码的安全性(完全避免unwrap()):
fn clean<T, E>(data: Vec<Result<Option<T>, E>>) -> Result<Vec<T>, E> { data.into_iter() .filter_map(|res| res.transpose()) .collect() }
代码解释
Result::transpose()是核心:它会把Result<Option<T>, E>类型转换为Option<Result<T>, E>,正好匹配你需要的分支逻辑:- 输入
Ok(Some(t))→ 输出Some(Ok(t)),保留有效元素 - 输入
Ok(None)→ 输出None,后续被filter_map过滤掉 - 输入
Err(e)→ 输出Some(Err(e)),保留错误信息供后续collect处理
- 输入
filter_map()会自动过滤掉None值,只保留Result<T, E>类型的元素- 最后
collect()会将迭代器中的Result序列聚合为Result<Vec<T>, E>:如果遇到任何Err就立即终止并返回该错误,否则返回所有有效元素组成的Vec<T>
和原有代码的对比
- 这段代码完全等价于你第一段的逻辑,但更简洁,可读性更强
- 相比第二段代码,它避免了
unwrap()带来的panic风险,同时代码长度更短
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

