有没有一种混乱的方式来链接返回Option值的函数的结果? [英] Is there a non-messy way to chain the results of functions that return Option values?
问题描述
我有一些看起来像这样的代码:
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)
})
})
})
f
,g
和h
返回Option
值的位置.我需要在do_something_with
计算中使用所有中间值(a
,b
,c
和d
).压痕很深.有一个更好的方法吗?理想情况下,它看起来像这样(当然不起作用):
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 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屋!