当谓词返回Result <bool,_ =“”>?</bool,>时,如何过滤迭代器?

时间:2015-01-20 01:04:42

标签: rust

我希望过滤迭代器,但我的谓词有可能失败。当谓词失败时,我想使整个函数失败。在此示例中,我希望work返回Result生成的maybe

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>`

1 个答案:

答案 0 :(得分:3)

您可以将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