rust - 映射潜在故障的好方法

标签 rust

<分区>

我正在尝试解析一系列 Json具有取消整个功能的潜在故障的对象。

理想情况下,我会做类似的事情:

fn .... -> Result<Vec<Video>, YoutubeParseError> {
    ...
    let videos = try!(doc.find("items").
        and_then(Json::as_array).
        ok_or(YoutubeParseError));

    Ok(videos.into_iter().
        map(|item| try!(json_to_video(item))).
        collect())
}

但当然 try 不会逃脱 map()出错而不是 Result<Vec<Video>,_> , 我得到 Vec<Result<Video,_>> .我可以将其重写为手动迭代将元素添加到新的 vec 中,但我觉得我缺少一些更简单的处理方法。

是否有一些现有的功能可以让我从 Iter<Result<T>>Result<Vec<T>,_>容易吗?

最佳答案

在函数式编程语言中,您可以将选项和结果视为容器,Rust 也是类似的,因此您可以对它们进行 map/flat_map。您可以使用 flat_map 来做到这一点。如果 videos 已经是一个向量,您可以根据 flat_mapped 长度测试 Ok 的预期数量来决定是否返回 确定

但是,您应该尽量保持惰性,不要在第一次失败后继续解析。 take_while 是这里的一个选项。无论哪种方式,您都需要跟踪是否在此过程中看到了 parse_failure。像下面这样的东西是有效的——它演示了 flat_map 如何丢弃 Error,但它解析了不必要的东西。您还可以使用 .filter 然后使用 .map 来获取解析结果

fn get_videos(test: &Vec<&str>) -> Result<Vec<u32>, &'static str> {
    let videos = ...
    let expected = videos.len();
    let extracted = v.into_iter().flat_map(|x| json_to_video(x)).collect();
    if extracted.len() == expected {
        Ok(extracted)
    } else {
        Err("not_ok")
    }
}

这里有一个懒惰的选项 -

let extracted = videos.map(|x|json_to_video(x))
                      .take_while(|x|x.is_ok())
                      .map(|x|x.ok().unwrap())
                      .collect() 

您可以调用 unwrap,因为您从第一次失败开始就丢弃了所有内容。现在你返回 Ok 如果 extracted.len() == videos.len()

关于rust - 映射潜在故障的好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38841156/

相关文章:

rust - 为什么枚举需要额外的内存大小?

rust - 打印!借用或拥有变量?

rust - 为什么 `tokio::main` 报告错误 "cycle detected when processing"?

rust - 除非我使用临时变量,否则为什么我不能插入 Vec 的 dyn Trait?

performance - Rust 的 Option 类型的开销是多少?

string - 如何复制向量的第一个和最后一个元素?

rust - Handlebars 三个阵列在一个循环中

graph - 如何使用Serde和Petgraph对图进行序列化和反序列化?

rust - 如果不实现 Copy 或 Clone 特征,重用借用的结构字段的最佳方法是什么?

rust - 在 Rust 中使用工厂模式时指定生命周期