Randal Robinson
Randal Robinson

Reputation: 21

How do I mix boolean comparisons and 'if let' statements in a clean way?

I am writing a function which depends on comparing booleans, and also checking an enum's type using the 'if let' syntax. Is there a cleaner way than what I have below?

fn is_mine(&self, row: i32, col: i32) -> bool {
    if self.bounds.is_in_bounds(row, col) {
        if let MineCell::Mine = self.field[row as usize][col as usize] {
            return true;
        }
    }

    false
}

This works, but it feels dirty by returning true/false as the only statement inside of an 'if' block. In my case, the boolean comparison in the .is_in_bounds() member has to occur first, then the if let check on the enum's type is safe to do.

This is technically correct, but I feel like there has to be a more idiomatic way to do this. I've seen posts here and elsewhere about how to properly stack if let statements, but nothing about mixing boolean comparisons and if let comparisons.

Should I accept the correct but ugly form of the above code?

Upvotes: 1

Views: 437

Answers (2)

justinas
justinas

Reputation: 6857

If your enum implements PartialEq, this should also work:

fn is_mine(&self, row: i32, col: i32) -> bool {
    self.bounds.is_in_bounds(row, col)
        && self.field[row as usize][col as usize] == MineCell::Mine
}

Upvotes: 2

Jmb
Jmb

Reputation: 23264

You can do it in a single expression using std::mem::discriminant like this:

fn is_mine(&self, row: i32, col: i32) -> bool {
    use std::mem::discriminant;

    self.bounds.is_in_bounds(row, col)
        && discriminant(&self.field[row as usize][col as usize])
            == discriminant(&MineCell::Mine)
}

Remember that in Rust, logical operators short-circuit, so the part after the && will only be executed if the first part is true.

Upvotes: 2

Related Questions