Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a shorthand for evaluating whether a refutable pattern matches?

As far as I can tell, refutable patterns can only be tested in match, if let, and while let expressions. To illustrate what I would like to do, consider the use of the => syntax from the match statement in the following context:

let val = get_optional_value();
if val => Some(inner) {
    do_something(inner);
}

I could use an if let statement, but a more useful context would be in short closures:

get_optional_value()
    .filter(|iv| iv => InnerVariant::VariantA)
    .and_then(/* ... */)

As far as I can tell, the only solution to achieving this using pattern matching would be:

get_optional_value()
    .filter(|iv| {
        if let InnerVariant::VariantA = iv {
            true
        } else {
            false
        }
    })
    .and_then(/* ... */)

There is a similar question that did not get answered but the comments do point to the use of the ? operator that solves a related corner case for std::result::Result.

like image 689
mallwright Avatar asked Dec 31 '22 00:12

mallwright


1 Answers

Rust 1.42 added the matches! macro. matches!(X, Y) returns a boolean indicating whether expression X matches the pattern Y.

In your case, it could be used like this:

get_optional_value()
    .filter(|iv| matches!(iv, InnerVariant::VariantA))
    .and_then(/* ... */)

This does not let you bind new names, you can only access the "inner" data in an optional if guard.

like image 110
justinas Avatar answered Jan 31 '23 06:01

justinas