rust 如何将Vec〈结果〈T,E>>转换为结果〈Vec< T>,E>?[duplicate]

wvyml7n5  于 2023-02-04  发布在  其他
关注(0)|答案(2)|浏览(133)
    • 此问题在此处已有答案**:

How do I stop iteration and return an error when Iterator::map returns a Result::Err?(4个答案)
两年前关闭了。
有没有更好的方法把Vec<Result<T, E>>转换成Result<Vec<T>, E>?如果向量的所有值都是Ok<T>,我想得到Ok<Vec<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子句,这个子句永远不会被使用,Err(el.unwrap_err())看起来毫无用处。换句话说,代码做了很多事情只是为了让编译器满意。我觉得这是一种很常见的情况,有更好的方法来完成它。

yqlxgs2m

yqlxgs2m1#

Result<T, E>上的迭代器可以直接被collect()-艾德成Result<Vec<T>, E>;也就是说,您整个函数可以替换为:

let new: Result<Vec<T>, E> = v.into_iter().collect()
gdrx4gfi

gdrx4gfi2#

您可以在Result上使用FromIterator trait实现(.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()
}

相关问题