Как правильно смешать булевы сравнения и операторы if if? - PullRequest
1 голос
/ 07 октября 2019

Я пишу функцию, которая зависит от сравнения логических значений, а также от проверки типа enum с использованием синтаксиса if if. Есть ли более чистый способ, чем у меня ниже?

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
}

Это работает, но кажется грязным, возвращая true / false как единственный оператор внутри блока if. В моем случае сначала должно выполняться булево сравнение в элементе .is_in_bounds(), а затем проверка if let на тип enum безопасна.

Это технически правильно, но я чувствую, что должен быть более идиоматический способ сделать это. Здесь и в других местах я видел сообщения о том, как правильно составлять if let операторы, но ничего о смешанных логических и if let сравнениях.

Должен ли я принять правильную, но безобразную форму приведенного выше кода?

Ответы [ 2 ]

1 голос
/ 07 октября 2019

Если ваш enum реализует PartialEq, это также должно работать:

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
}
1 голос
/ 07 октября 2019

Вы можете сделать это в одном выражении, используя std::mem::discriminant следующим образом:

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)
}

Помните, что в Rust логические операторы замыкаются накоротко, поэтому часть после && будет выполнено, только если первая часть верна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...