rust - Is there a non-messy way to chain the results of functions that return Option values? -
i have code looks this:
f(a).and_then(|b| { g(b).and_then(|c| { h(c).map(|d| { do_something_with(a, b, c, d) }) }) })
where f
, g
, , h
return option
values. need use intermediate values (a
, b
, c
, , d
) in do_something_with
calculation. indentation deep. there better way this? ideally (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 }
the rust standard library defines try!
macro solves problem result
. macro looks 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)) } }) }
what is, if argument err
, returns function err
value. otherwise, evaluates value wrapped in ok
. macro can used in function returns result
, because returns error meets.
we can make similar macro option
:
macro_rules! try_opt { ($expr:expr) => (match $expr { ::std::option::option::some(val) => val, ::std::option::option::none => return none }) }
you can use macro 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 doesn't return option }
Comments
Post a Comment