Is there a more idiomatic way to express something like the following?
fn main() {
let mut foo: Option<u8> = None;
match foo {
Some(foo_val) if ! (foo_val < 5) /* i.e. the negation of my acceptance condition */ => {}
_ => { foo.replace(5); }
}
}
It seems like most of the time there's an alternative to having an arm that doesn't do anything, but I've been unable to find one for this particular case.
What I'd like to say is the more direct if foo.is_none() || /* some way to extract and test the inner value */ { ... }
, or perhaps some chaining trick that's eluding me.
EDIT: correct solution for Rust >= 1.82 https://stackoverflow.com/a/79158152/2408867
// in None case
// │ in Some(_) case
// ┌┴─┐ ┌───────────────────┐
if foo.map_or(true, |foo_val| foo_val < 5) {
// ...
}
For more information see Option::map_or
.
There are many ways to do it. One of the simplest (and arguably most readable) is something like this:
if foo.unwrap_or(0) < 5 {
...
}
The above will be true in both cases:
foo
is Some
with a value smaller than 5
;foo
is None
.In some more complex scenarios, where the "default" value needs to be calculated and performance is critical, you might want to consider unwrap_or_else
.
As Lukas suggested, the map_or
method can also be used. Note that arguments passed to map_or
are eagerly evaluated, so if performance is critical, you might want to consider map_or_else
as an alternative.
The is_some_and
method has been stabilized in Rust 1.70. Here is an example:
if name.is_some_and(|s| s.len() > 50) {
println!("This is a long name!");
}
In many cases that should be more readable than map_or
/ map_or_else
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With