有没有一种混乱的方式来链接返回Option值的函数的结果? [英] Is there a non-messy way to chain the results of functions that return Option values?

查看:76
本文介绍了有没有一种混乱的方式来链接返回Option值的函数的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些看起来像这样的代码:

I have some code that looks like this:

f(a).and_then(|b| {
    g(b).and_then(|c| {
        h(c).map(|d| {
            do_something_with(a, b, c, d)
        })
    })
})

fgh返回Option值的位置.我需要在do_something_with计算中使用所有中间值(abcd).压痕很深.有一个更好的方法吗?理想情况下,它看起来像这样(当然不起作用):

Where f, g, and h return Option values. I need to use all the intermediate values (a, b, c, and d) in the do_something_with calculation. The indentation is very deep. Is there a better way to do this? Ideally it would look something like this (which of course doesn't work):

try {
    let b = f(a);
    let c = g(b);
    let d = h(c);
    do_something_with(a, b, c, d)
} rescue NonexistentValueException {
    None
}

推荐答案

问号运算符现在支持Option,因此您可以将函数编写为

Rust 1.22

The question mark operator now supports Option, so you can write your function as

fn do_something(a: i32) -> Option<i32> {
    let b = f(a)?;
    let c = g(b)?;
    let d = h(c)?;
    do_something_with(a, b, c, d) // wrap in Some(...) if this doesn't return an Option
}

Rust 1.0

Rust标准库定义了try!宏(以及?运算符,从

Rust 1.0

The Rust standard library defines a try! macro (and, equivalently, the ? operator, as of Rust 1.13) that solves this problem for Result. The macro looks like this:

macro_rules! try {
    ($expr:expr) => (match $expr {
        $crate::result::Result::Ok(val) => val,
        $crate::result::Result::Err(err) => {
            return $crate::result::Result::Err($crate::convert::From::from(err))
        }
    })
}

如果参数为Err,它将从具有该Err值的函数返回.否则,它将求值为Ok中包装的值.该宏只能在返回Result的函数中使用,因为它会返回遇到的错误.

If the argument is Err, it returns from the function with that Err value. Otherwise, it evaluates to the value wrapped in Ok. The macro can only be used in a function that returns Result, because it returns the error it meets.

我们可以为Option创建一个类似的宏:

We can make a similar macro for Option:

macro_rules! try_opt {
    ($expr:expr) => (match $expr {
        ::std::option::Option::Some(val) => val,
        ::std::option::Option::None => return None
    })
}

然后您可以像这样使用此宏:

You can then use this macro like this:

fn do_something(a: i32) -> Option<i32> {
    let b = try_opt!(f(a));
    let c = try_opt!(g(b));
    let d = try_opt!(h(c));
    do_something_with(a, b, c, d) // wrap in Some(...) if this doesn't return an Option
}

这篇关于有没有一种混乱的方式来链接返回Option值的函数的结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆