当谓词返回一个Result<bool, _>时,我该如何过滤迭代器?

5

我希望迭代器被过滤,但是我的谓词有可能失败。当谓词失败时,我希望整个函数也失败。在这个例子中,我希望work返回由maybe生成的Result

fn maybe(v: u32) -> Result<bool, u8> {
    match v % 3 {
        0 => Ok(true),
        1 => Ok(false),
        2 => Err(42),
    }
}

fn work() -> Result<Vec<u32>, u8> {
    [1, 2, 3, 4, 5].iter().filter(|&&x| maybe(x)).collect()
}

fn main() {
    println!("{:?}", work())
}

error[E0308]: mismatched types
  --> src/main.rs:10:45
   |
10 |         [1, 2, 3, 4, 5].iter().filter(|&&x| maybe(x)).collect()
   |                                             ^^^^^^^^ expected bool, found enum `std::result::Result`
   |
   = note: expected type `bool`
              found type `std::result::Result<bool, u8>`

error[E0277]: the trait bound `std::result::Result<std::vec::Vec<u32>, u8>: std::iter::FromIterator<&u32>` is not satisfied
  --> src/main.rs:10:55
   |
10 |         [1, 2, 3, 4, 5].iter().filter(|&&x| maybe(x)).collect()
   |                                                       ^^^^^^^ a collection of type `std::result::Result<std::vec::Vec<u32>, u8>` cannot be built from an iterator over elements of type `&u32`
   |
   = help: the trait `std::iter::FromIterator<&u32>` is not implemented for `std::result::Result<std::vec::Vec<u32>, u8>`

我认为在你的情况下最好使用一个循环: try!(maybe(x)) 并将值推入一个可变的 Vec<u32> - rodrigo
1个回答

6
您可以将Result <bool,u8>转换为Option <Result<u32,u8>>,也就是说,将bool提取到Option中并放入值,并使用filter_map
fn maybe(v: u32) -> Result<bool, u8> {
    match v % 3 {
        0 => Ok(true),
        1 => Ok(false),
        _ => Err(42),
    }
}

fn work() -> Result<Vec<u32>, u8> {
    [1, 2, 3, 4, 5]
        .iter()
        .filter_map(|&x| match maybe(x) {
            Ok(true) => Some(Ok(x)),
            Ok(false) => None,
            Err(e) => Some(Err(e)),
        })
        .collect()
}

fn main() {
    println!("{:?}", work())
}

playground


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接