This is my first post to users.rust-lang. I'm new to the language and I'm trying to figure out if there's an idiomatic way to exit a function early with Ok(())
in the case that None
is received. But I want to proceed to immutably assign in the original scope if Some
is received.
For example, imagine that we have a function with this signature.
fn maybe_int() -> Option<u32> {
// sometimes I return None, othertimes I return Some(x)
Some(1)
}
And we want to use that function from a calling function that returns a Result
. I want to assign the value of Some
in the calling scope, and exit the calling function with Ok(())
if None
was received from maybe_int
.
But this cannot be done with unwrap_or_else
fn some_caller() -> Result<(), String> {
let value = maybe_int().unwrap_or_else(|| {
// Help, I want some_caller to return Ok(()) now
// but I'm stuck in a lambda.
1 // The one is here just so that it compiles, but I
// actually want some_caller to exit Ok
});
// proceed to do things with value, preferably in some_caller's scope instead of
// an indented block. some things might_error()?;
Ok(())
}
One way that I know of to write this code is to match on the result, but then I'm left with my value
in an inner scope when I wanted it in the top-level scope.
fn one_solution() -> Result<(), String> {
match maybe_int() {
None => Ok(()),
Some(value) => {
// yuck, proceed to do stuff with value in this deeply
// indented block. some of it might_error()?;
Ok(())
}
}
}
The only other thing I can think of is to start with a mut
and assign to it inside the Some
block, but this seems very clunky. I suppose I could even let value = value;
after to make it immutable, but yuck.
fn another_solution() -> Result<(), String> {
// this works but seems very non-idiomatic and leaves me with a mut value. yuck.
let mut value: u32 = 0;
if let Some(temp) = maybe_int() {
value = temp;
} else {
return Ok(());
}
// do stuff with value. some of it might_error()?;
Ok(())
}
So the question: is there an idiomatic way to do what I'm trying to do? That is, unwrap the Option into the original scope, but return early from the function with Ok(())
if None
is received.
P.S. My aversion to doing everything in the nested Some block of one_solution
might just be stylistic baggage that I'm bringing with me.