Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to combine two patterns, one with a match guard, in the same match arm?

Tags:

rust

I want to check if a string contains '$' and if there is something after the '$':

I tried this code:

fn test(s: String) {
    match s.find('$') {
        None | (Some(pos) if pos == s.len() - 1) => {
          expr1();
        }
        _ => { expr2(); }
    }
}

But it doesn't compile:

error: expected one of `)` or `,`, found `if`

Is it impossible to combine None and Some in one match-arm?

If so, is there a simple way to not duplicate expr1() except moving it into a separate function?

like image 227
user1244932 Avatar asked Feb 20 '17 22:02

user1244932


People also ask

Does Rust have pattern matching?

Patterns are a special syntax in Rust for matching against the structure of types, both complex and simple. Using patterns in conjunction with match expressions and other constructs gives you more control over a program's control flow.

How match works in Rust?

A match expression branches on a pattern. The exact form of matching that occurs depends on the pattern. A match expression has a scrutinee expression, which is the value to compare to the patterns. The scrutinee expression and the patterns must have the same type.

How do you match types in Rust?

TLDR: in Rust, to match over type, we create a trait, implement a function for each type and call it on the element to match. Surround it with backticks to mark it as code. Single backticks for inline code, triple backticks for code blocks.


1 Answers

It is impossible to have the match-guard (the if thingy) apply to only one pattern alternative (the things separated by | symbols). There is only one match-guard per arm and it applies to all patterns of that arm.

However, there are many solutions for your specific problem. For example:

if s.find('$').map(|i| i != s.len() - 1).unwrap_or(false) {
    expr2();
} else {
    expr1();
}
like image 150
Lukas Kalbertodt Avatar answered Sep 18 '22 14:09

Lukas Kalbertodt