In your example you want to not just continue, break or return a regular value, but return an error. For that particular case, the Aiden4's answer is the way to go. But I've been in situations where I want to unwrap or (in the case of None) directly continue, break or return a non-error value. Rust (still) doesn't provide a short and concise way to do exactly that.
Here is a "one-liner" which kinda does the trick, but is still a bit verbose:
let v = if let Some(d) = some_option_value { d } else { continue; };
If you want a shorter solution, here are two options...
A macro
You can write a macro like this:
macro_rules! unwrap_or {
($e:expr, $or_do_what:expr) => {
if let Some(d) = $e { d } else { $or_do_what }
};
}
That will allow you to write code like this:
let options = vec![Some(74), None, Some(9)];
for o in options {
let v = unwrap_or!(o, continue);
// ...
}
That's a trivial example, but I think the biggest benefit can come if you need to perform multiple checks, so that instead of writing something "idiomatic" like this:
for thing in things {
if let Some(a) = thing {
// ...
if let Some(b) = a.another_opt {
// ...
if let Some(c) = a.yet_another_opt {
// ...
}
}
}
}
, you can simplify the code by avoiding the nesting of multiple blocks like this:
for thing in things {
let a = unwrap_or!(thing, continue);
// ...
let b = unwrap_or!(a.another_opt, continue);
// ...
let c = unwrap_or!(a.yet_another_opt, continue);
// ...
}
Whether that's a good practice is subjective, of course.
let...else (unstable)
There is an unstable let...else feature, which is intended to solve the problem. Example:
#![feature(let_else)]
...
let options = vec![Some(74), None, Some(9)];
for o in options {
let Some(v) = o else { continue };
println!("v = {v}");
}