我有一个返回Result的函数:

fn find(id: &Id) -> Result<Item, ItemError> {
    // ...
}

然后另一个用户这样使用它:

let parent_items: Vec<Item> = parent_ids.iter()
    .map(|id| find(id).unwrap())
    .collect();

我如何处理map次迭代中的任何一次失败的情况?

我知道我可以使用flat_map,在这种情况下,错误结果将是ignored:

let parent_items: Vec<Item> = parent_ids.iter()
    .flat_map(|id| find(id).into_iter())
    .collect();

Result的迭代器根据成功状态有0或1项,如果是0,flat_map将过滤掉它.

但是,我不想看到ignore个错误,我想让整个代码块停止并返回一个新错误(基于映射中出现的错误,或者只是转发现有错误).

我如何最好地处理这个Rust 的?

推荐答案

Result implements FromIterator,因此您可以将Result移到外部,迭代器将处理其余部分(包括在发现错误时停止迭代).

#[derive(Debug)]
struct Item;
type Id = String;

fn find(id: &Id) -> Result<Item, String> {
    Err(format!("Not found: {:?}", id))
}

fn main() {
    let s = |s: &str| s.to_string();
    let ids = vec![s("1"), s("2"), s("3")];

    let items: Result<Vec<_>, _> = ids.iter().map(find).collect();
    println!("Result: {:?}", items);
}

Playground

Rust相关问答推荐

使用windows crate Rust 展示windows

使用InlineTables序列化toml ArrayOfTables

计算具有相邻调换且没有插入或删除的序列的距离

为什么函数不接受选项T参数的所有权?

如何创建引用构造函数拥有的变量的对象?

当T不执行Copy时,如何返回Arc Mutex T后面的值?

Tokio_Postgres行上未显示退回特性的生存期,且生命周期 不够长

可以为rust构建脚本编写单元测试吗?

如何在不调用Collect()的情况下为新型vec实现IntoIterator?

为什么Rust不支持带关联常量的特征对象?

Tokio';s io::用Cursor拆分<;Vec<;u8>>;赢得';t get the full writted data

Rust typestate 模式:实现多个状态?

一个函数调用会产生双重borrow 错误,而另一个则不会

使用 traits 时,borrow 的值不会存在足够长的时间

将一片字节复制到一个大小不匹配的数组中

你能告诉我如何在 Rust 中使用定时器吗?

当特征函数依赖于为 Self 实现的通用标记特征时实现通用包装器

为什么我可以在没有生命周期问题的情况下内联调用 iter 和 collect?

A 有一个函数,它在 Option<> 类型中时无法编译,但在 Option<> 类型之外会自行编译.为什么?

如何重写这个通用参数?