如何将Vec <Result <T,E >>转换为Result <Vec <T>,E>?

问题描述

是否有任何自以为是和更优雅的方式将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()
}