问题描述
是否有任何自以为是和更优雅的方式将Vec<Result<T,E>>
转换为Result<Vec<T>,E>
?如果向量的所有值都是Ok<Vec<T>>
,并且如果至少一个是Ok<T>
,我想得到Err<E>
。
示例:
Err<E>
我正在寻找一种更具声明性的方式来编写此代码。这个函数迫使我写一个fn vec_of_result_to_result_of_vec<T,E>(v: Vec<Result<T,E>>) -> Result<Vec<T>,E>
where
T: std::fmt::Debug,E: std::fmt::Debug,{
let mut new: Vec<T> = Vec::new();
for el in v.into_iter() {
if el.is_ok() {
new.push(el.unwrap());
} else {
return Err(el.unwrap_err());
}
}
Ok(new)
}
子句,它将永远不会被使用,而where
看起来却毫无用处。换句话说,代码做了很多事情只是为了使编译器满意。我觉得这是很普通的情况,有更好的方法可以做到。
解决方法
可以将Result<T,E>
上的迭代器直接collect()
编辑为Result<Vec<T>,E>
;也就是说,您的整个功能可以替换为:
let new: Result<Vec<T>,E> = v.into_iter().collect()
,
您可以使用FromIterator
trait implementation on Result
(.collect()
在目标类型上需要FromIterator
并调用它来从Iterator
进行转换):
fn vec_of_result_to_result_of_vec<T,E>(v: Vec<Result<T,E>>) -> Result<Vec<T>,E> {
v.into_iter().collect()
}