Это плохо, чтобы явно сравнить с логическими константами, например если (b == false) в Java? - PullRequest
70 голосов
/ 18 апреля 2010

Разве плохо писать:

if (b == false) //...

while (b != true) //...

Это всегда лучше вместо этого написать:

if (!b) //...

while (!b) //...

Предположительно, нет разницы в производительности (или есть?), Но как вы оцениваете четкость, краткость, ясность, читаемость и т. Д. Между ними?

Обновление

Чтобы ограничить субъективность, я также был бы признателен за любые цитаты из руководящих принципов авторитетного стиля кодирования, над которыми всегда предпочтительнее или которые использовать, когда.


Примечание : имя переменной b используется только в качестве примера, ala foo и bar.

Ответы [ 14 ]

62 голосов
/ 18 апреля 2010

Это не обязательно плохо, это просто лишнее. Кроме того, фактическое имя переменной много весит. Я бы предпочел например if (userIsAllowedToLogin) выше if (b) или даже хуже if (flag).

Что касается производительности, компилятор оптимизирует ее любым способом.

Обновление : что касается авторитетных источников, я не могу найти что-то явно в Соглашениях по кодированию солнца , но по крайней мере Checkstyle имеет SimplifyBooleanExpression модуль, который предупредит об этом.

46 голосов
/ 18 апреля 2010

Вы не должны использовать первый стиль. Я видел, как люди используют:

  • if ( b == true )
  • if ( b == false )

Лично мне трудно читать, но это сносно. Однако большая проблема, с которой я столкнулся в этом стиле, заключается в том, что он приводит к невероятно нелогичным примерам, которые вы показали:

  • if ( b != true )
  • if ( b != false )

Потребуется больше усилий со стороны читателя, чтобы определить намерение авторов. Лично я считаю, что явное сравнение с истинным или ложным является избыточным и, следовательно, более трудным для чтения, но это я.

32 голосов
/ 18 апреля 2010

Это сильно зависит от вкуса.

Лично я обнаружил, что if (!a) { намного меньше для чтения (РЕДАКТИРОВАТЬ: для меня), чем if (a == false) { и, следовательно, более подвержен ошибкам при обслуживании кода позже, и я преобразовал используйте последнюю форму.

В основном мне не нравится выбор символов для логических операций вместо слов (C против Паскаля), потому что me a = 10 and not b = 20 читается легче, чем a == 10 && !(b==20), но это так в Java .

Любой, кто ставит «== ложный» подход в пользу «!» очевидно, никогда не смотрел на код слишком долго и пропустил этот восклицательный знак. Да, вы можете получить слепой код.

24 голосов
/ 18 апреля 2010

Основная причина, по которой вы не должны использовать первый стиль, заключается в том, что оба они действительны:

if (b = false) //...

while (b = true) //...

То есть, если вы случайно пропустите один символ, вы создаете назначение вместо сравнения. Выражение присваивания оценивается по значению, которое было присвоено, поэтому первый приведенный выше оператор присваивает значение false b и false Второй присваивает true b, поэтому он всегда оценивается как true, независимо от того, что вы делаете с b внутри цикла.

11 голосов
/ 18 апреля 2010

Я никогда не видел первого, кроме как в коде, написанном новичками; это всегда последнее, и я не думаю, что кто-то действительно смущен этим. С другой стороны, я думаю

int x;
...
if(x) //...

против

if(x != 0) //...

гораздо более спорно, и в этом случае я предпочитаю второй

7 голосов
/ 18 апреля 2010

ИМХО, я думаю, что если вы просто сделаете имена переменных bool с добавлением "Is", это будет самоочевидно и более значимым, а затем вы можете удалить явное сравнение с true или false

Пример:

isEdited  // use IsEdited in case of property names
isAuthorized // use IsAuthorized in case of property names

и т.д.

5 голосов
/ 18 апреля 2010

Я предпочитаю первое, потому что оно понятнее.Машина может читать одинаково хорошо, но я пытаюсь написать код для чтения людей , а не только машины.

3 голосов
/ 21 мая 2013

Я предпочитаю длительный подход, но я сравниваю использование == вместо != 99% времени.

Я знаю, что этот вопрос касается Java, но я часто переключаюсь между языками, и в C#, например, сравнение с (для isntance) == false может помочь при работе с типами bool, допускающими обнуляемость. Так что я получил привычку сравнивать с true или false, но с использованием оператора ==.

Я делаю это:

if(isSomething == false) или if(isSomething == true)

но я ненавижу это:

if(isSomething != false) или if(isSomething != true)

по понятным причинам читабельности!

Пока ваш код читается, это не имеет значения.

2 голосов
/ 27 апреля 2018

Это мой первый ответ по StackOverflow, так что будьте добры ... Недавно во время рефакторинга я заметил, что 2 блока кода имеют почти одинаковый код, но один из них имеет

for (Alert alert : alerts) {
    Long currentId = alert.getUserId();

    if (vipList.contains(currentId)) {
        customersToNotify.add(alert);

        if (customersToNotify.size() == maxAlerts) {
            break;
        }
    }
}

, а другой -

for (Alert alert : alerts) {
    Long currentId = alert.getUserId();

    if (!vipList.contains(currentId)) {
        customersToNotify.add(alert);

        if (customersToNotify.size() == maxAlerts) {
            break;
        }
    }
}

, поэтому в этом случае имело смысл создать метод, который работал бы для обоих подобных условий, используя boolean == condition, чтобы перевернуть значение

private void appendCustomersToNotify(List<Alert> alerts
        List<Alert> customersToNotify, List<Long> vipList, boolean vip){

    for (Alert alert : alerts) {
        Long currentId = alertItem.getUserId();

        if (vip == vipList.contains(currentId)) {
            customersToNotify.add(alertItem);

            if (customersToNotify.size() == maxAlerts) {
                break;
            }
        }
    }
}
2 голосов
/ 18 апреля 2010

Лично я бы реорганизовал код, чтобы не использовать отрицательный тест. например.

if (b == false) {
   // false
} else {
   // true
}

или

boolean b = false;
while(b == false) {
  if (condition)
      b = true;
}

ИМХО, в 90% случаев код может быть реорганизован, поэтому отрицательный тест не требуется.

...