1

I am trying to match an enum struct. This enum has different variants with different (or none) fields, such as:

enum Enum {
    One {n : usize},
    Two ,
} 

The match block that I am trying to achieve looks like:

match m {
    Enum::One{n: special_value} => {
        println!("it is special! {}", special);
    }
    Enum::One{n} => {
        println!("not special: {}", n);
    }
    Enum::Two => {
        println!("not special");
    }
}

If I define let m = Enum::One{n: 3} and let special_value = 8 the code prints it is special! 3. This should print not special: 3.

If I change the match block to (note that I changed the variable special_value variable to the literal 8:

match m {
    Enum::One { n: 8 } => {
        println!("it is special!");
    }
    Enum::One { n } => {
        println!("not special: {}", n);
    }
    Enum::Two => {
        println!("not special");
    }
}

Now defining let m = Enum::One { n: 3 } it prints as desired not special: 3.

In my actual project case, I cannot use a literal to do the match the value comes from the function call as a variable.

For this porpouse I can use this match block (note the special case has been removed and replaced by an if clause inside the general case) :

match m {
    Enum::One { n } => {
        if n == special_value {
            println!("it is special! {}", special_value);
        } else {
            println!("not special: {}", n);
        }
    }
    Enum::Two => {
        println!("not special");
    }
}

Is it possible to use a variable inside the match, or am I forced to use the if clause? What is the reason?

javier
  • 113
  • 9
  • 2
    Related: https://stackoverflow.com/questions/28225958/why-is-this-match-pattern-unreachable-when-using-non-literal-patterns – Jmb Sep 07 '22 at 12:24

1 Answers1

1

yes. you can add if statements on the match arm without creating if block inside match arm block

does this works for you?

enum Enum {
    One {
        n: usize
    },
    Two
}

fn main() {
    let special_value = 123;
    let m = Enum::One { n: 123 };
    match m {
        
        Enum::One { n } if n == special_value => println!("it is special! {}", special_value),
        Enum::One { n } => println!("not special: {}", n),
        Enum::Two => {
            println!("not special");
        }
    }
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=acfaae3976e7ca9fcf096c635a4daf98

works for me.

alexzander
  • 1,586
  • 1
  • 9
  • 21