Match operators vs if/else if/else, errors4 rustlings

I've been attempting the errors4 exercise in rustlings as an introduction to the language, and I know a valid solution contains the following code within the new() function:

if value == 0 {
    Err(CreationError::Zero)
} else if value < 0 {
    Err(CreationError::Negative)
} else {
    Ok(PositiveNonzeroInteger(value as u64))
}

Every 'rustlings solutions' I've seen so far on GitHub uses either the same code as above or something similar. Whilst it's easy to read, I have an aversion to using if/else if/else statements as I think they can get fairly clumsy. I tried to figure out a solution using the match operator, and the following code passed the tests:

match (value == 0, value < 0) {
    (true, _) => Err(CreationError::Zero),
    (_, true) => Err(CreationError::Negative),
    (false, false) => Ok(PositiveNonzeroInteger(value as u64)),
}

I feel, though, that this is somewhat less human-readable than the first code block. Could someone advise which approach is typically preferable/more idiomatic when coding in Rust? Thanks!

You can use range pattern for it.

match value {
    0 => Err(CreationError::Zero),
    i64::MIN..=-1 => Err(CreationError::Negative),
    1..=i64::MAX => Ok(PositiveNonzeroInteger(value as u64),
}

Note that like other patterns the compiler check the patterns are exhaustive. Try change the third arm to start from the 2 and see what happens.

4 Likes

Another possible option is to use match guards to get rid of the big if-else chain.

match value {
    value if value == 0 => Err(CreationError::Zero),
    value if value < 0 => Err(CreationError::Negative),
    value => Ok(PositiveNonzeroInteger(value as u64)),
}
1 Like

You could use the Ord::cmp method:

use std::cmp::Ordering;

match value.cmp(&0) {
    Ordering::Greater => Ok(PositiveNonzeroInteger(value as u64)),
    Ordering::Equal => Err(CreationError::Zero),
    Ordering::Less => Err(CreationError::Negative),
}
7 Likes

Thanks all. Much appreciated

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.