Greater than/Less than in a match block?

Hello,
How do I check if an i32 variable is less than/greater than a number in a match block?

A comparison returns bool. If you're trying to use that in a match block, you're just using a glorified "if". You may just have to special case an enum or use a nested "if".

I need to use a match block because I have a bunch of other thing to compare with the variable.

Also, is there an "or" operator for if statement?

You can use Ord::cmp directly.

match a.cmp(&b) {
    Ordering::Less => {},
    Ordering::Greater => {},
    Ordering::Equal => {},
}

The or operator is the same as in many languages ||. I'd advise you follow a bit along the book for some time to learn the basics.

4 Likes

I don't want to compare it against a variable though, I want to compare it to a number. What I'm trying to do is check if the variable is either greater than two or less than one, and if that's true, then set the variable back to two.

That can be done with a simple if. Well, if you want use match, you could also use range patterns, but I don’t see how that would give you any benefit. I’m interpreting your “greater that” and “less than” to refer to strict inequality.

let mut x: i32 = some_value();

if x < 1 || x > 2 { x = 2 };

// or 

let mut x: i32 = some_value();

match x {
    i32::MIN..=1 | 3..=i32::MAX => x = 2,
    _ => ()
}
1 Like
let a = ...; // some number
let a = if a < 1 || a > 2 {
    2
} else {
    a
};
1 Like

Note that range patterns quite a special feature that specificly allows testing less-than-or-equal and greater-than-or-equal relations. Other, more complex, kinds of comparisons or tests can still be used in a match statement in the form of a guard which supports any kind of boolean-yielding expression as a condition.

let mut x: i32 = some_value();

match x {
    n if n < 1 || n > 2 => x = 2,
    _ => ()
}

which is a bit nonesensical to use on a simple variable. But if you do pattern matching, too, it can make sense

let mut x: Option<i32> = some_optional_value();

match x {
    Some(n) if n < 1 || n > 2 => x = Some(2),
    _ => ()
}
2 Likes
warning: value assigned to `selection` is never read

code:

mut selection if selection < 1 || selection > 2 => selection = 2

It looks like you're mixing up your syntax. The => operator can be used with match statements. If uses curly-braces. If it won't let you return with the no-semicolon syntax, you can always use a return command instead and put in the semicolon.

This is equivalent to:

mut newselection if oldselection < 1 || oldselection > 2 => newselection = 2

and hence you see that the value of newselection is never used before it's killed (reassigned)

If this is a match arm and you have both an outer variable named selection and match it against a pattern variable called selection then your pattern will introduce a selection into scope that's shadowing the original one. The mut you added probably comes from a compiler error, but if that's the case then you fixed the error the "wrong" way by blindly following compiler suggestions. You most likely don't want to mutate the local variable introduced by the pattern, hence adding mut is not the right approach, but renaming the variables is. See how my code used two different variable names x and n.

By the way, note that your "code example" is awfully incomplete; especially if you want to ask about specific compiler output such as warnings, more complete code examples are often crucial.

I think you are - technically - misinterpreting the error. The guard in OPs code (translated into your renaming scheme) does in fact refer to newselection variable. The problem is not that its value is never read before reassigning - in fact it is used (in the guard!) - no, the problem is that the new value 2 is never read after the reassigning (because the match arm ends and newselection goes after scope).

You're right.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.