Rust代码示例——18.6.结果集的遍历(Result的遍历)

看下面的示例,你会发现Iter::map在处理过程中会失败:

fn main() {

    let strings = vec!["tofu", "93", "18"];

    let numbers: Vec<_> = strings

        .into_iter()

        .map(|s| s.parse::<i32>())

        .collect();

    println!("Results: {:?}", numbers);

}

让我们逐步讨论处理这种错误的策略。

使用filter_map()来过滤掉失败的子项

filter_map()调用一个函数来过滤掉结果是None的子项:

fn main() {

    let strings = vec!["tofu", "93", "18"];

    let numbers: Vec<_> = strings

        .into_iter()

        .filter_map(|s| s.parse::<i32>().ok())

        .collect();

    println!("Results: {:?}", numbers);

}
使用map_err()和filter_map()收集错误的子项

map_err()可以调用错误处理函数,把它放入filter_map()函数内,正好可以处理过滤出的错误。

fn main() {

    let strings = vec!["42", "tofu", "93", "999", "18"];

    let mut errors = vec![];

    let numbers: Vec<_> = strings

        .into_iter()

        .map(|s| s.parse::<u8>())

        .filter_map(|r| r.map_err(|e| errors.push(e)).ok())

        .collect();

    println!("Numbers: {:?}", numbers);

    println!("Errors: {:?}", errors);

}
只使用collect(),当有错时,会导致整个失败

Result实现了FromIterator,因此result的集合(Vec<Result<t,E>>)可以被转换为包含结合的Result(Result<Vec<T>,E>)。一旦出现了Result::Err,整个遍历就会终止。

fn main() {

    let strings = vec!["tofu", "93", "18"];

    let numbers: Result<Vec<_>, _> = strings

        .into_iter()

        .map(|s| s.parse::<i32>())

        .collect();

    println!("Results: {:?}", numbers);

}

Option也可以这样操作。

使用partition()收集正确的值和失败的值
fn main() {

    let strings = vec!["tofu", "93", "18"];

    let (numbers, errors): (Vec<_>, Vec<_>) = strings

        .into_iter()

        .map(|s| s.parse::<i32>())

        .partition(Result::is_ok);

    println!("Numbers: {:?}", numbers);

    println!("Errors: {:?}", errors);

}

当你查看结果时,会发现每个子项都会包裹在Result内。这时就需要标准模板代码来进行解包了:
 

fn main() {

    let strings = vec!["tofu", "93", "18"];

    let (numbers, errors): (Vec<_>, Vec<_>) = strings

        .into_iter()

        .map(|s| s.parse::<i32>())

        .partition(Result::is_ok);

    let numbers: Vec<_> = numbers.into_iter().map(Result::unwrap).collect();

    let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect();

    println!("Numbers: {:?}", numbers);

    println!("Errors: {:?}", errors);

}

原文链接地址:Iterating over Results - Rust By Example

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值