rust - 使用结果迭代器最惯用的方式是什么?

标签 rust iterator map-function filterfunction rust-result

<分区>

我有这样的代码:

let things = vec![/* ...*/]; // e.g. Vec<String>
things
    .map(|thing| {
        let a = try!(do_stuff(thing));
        Ok(other_stuff(a))
    })
    .filter(|thing_result| match *thing_result {
        Err(e) => true,
        Ok(a) => check(a),
    })
    .map(|thing_result| {
        let a = try!(thing_result);
        // do stuff
        b
    })
    .collect::<Result<Vec<_>, _>>()

在语义方面,我想在第一个错误后停止处理。

上面的代码可以,但是感觉挺繁琐的。有没有更好的办法?我查看了文档中类似 filter_if_ok 的内容,但我还没有找到任何东西。

我知道 collect::<Result<Vec<_>, _>> ,而且效果很好。我特别想消除以下样板文件:

  • 在过滤器的闭包中,我必须使用 matchthing_result .我觉得这应该只是一个单行,例如.filter_if_ok(|thing| check(a)) .
  • 每次我使用map , 我必须包括一个额外的声明 let a = try!(thing_result);为了处理 Err 的可能性.同样,我觉得这可以抽象为 .map_if_ok(|thing| ...) .

我可以使用另一种方法来获得这种程度的简洁性,还是我只需要坚持下去?

最佳答案

有很多方法可以表达这个意思。

如果你只是想 panic ,使用.map(|x| x.unwrap()) .

如果您想要所有结果一个错误,collect进入 Result<X<T>> :

let results: Result<Vec<i32>, _> = result_i32_iter.collect();

如果您想要除错误之外的所有内容,请使用 .filter_map(|x| x.ok()).flat_map(|x| x) .

如果您想要第一个错误之前的所有内容,请使用 .scan((), |_, x| x.ok()) .

let results: Vec<i32> = result_i32_iter.scan((), |_, x| x.ok());

请注意,在许多情况下,这些操作可以与之前的操作结合使用。

关于rust - 使用结果迭代器最惯用的方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36368843/

相关文章:

clojure - 如何在Clojure中使用reduce实现map

multithreading - 是否可以在当前线程中在 Tokio 的当前线程上生成工作?

rust - 在存在借用的情况下,值(value)在闭包和组合器中过早下降

android - 如何将 Flutter 应用程序的构建过程与 Rust 代码集成?即在构建 Flutter 代码时,如何自动构建其 Rust 代码?

django - 在 Django 查询集上使用 iterator()

c++ - 递增迭代器以指向另一个迭代器的下一个元素

c++ - 转换多个迭代器元素

python - 用零替换python数组中的Nones

debugging - 如何在rust中编写 "non-assert"调试代码

javascript - 如何从数组中提取两列