Плохо ли явно сравнивать с булевыми константами, например, если (b = = false) в Java?


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

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

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

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

if (!b) //...

while (!b) //...

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

обновление

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


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

14 66

14 ответов:

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

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

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

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

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

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

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

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

это сильно дело вкуса.

лично я нашел это if (!a) { много меньше читабельный (EDIT: мне) чем if (a == false) { и, следовательно, более подвержены ошибкам при сохранении кода позже, и я преобразовал использовать последнюю форму.

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

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

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

if (b = false) //...

while (b = true) //...

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

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

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

vs

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

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

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

пример:

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

etc

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

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

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

это:

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

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

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

по очевидным причинам читаемости!

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

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

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

или

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

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

на мой взгляд это просто раздражает. Не то, что я бы вызвал шум, хотя.

нормальное руководство-никогда не тестировать против boolean. Некоторые утверждают, что дополнительная многословность добавляет ясности. Добавленный код может помочь некоторым людям, но каждый читатель должен будет прочитать больше кода.

сегодня утром, я потерял 1/2 часа, чтобы найти ошибку. Код был

    if ( !strcmp(runway_in_use,"CLOSED") == IPAS_FALSE)
      printf(" ACTIVE    FALSE \n");   else
      printf(" ACTIVE    TRUE \n");

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

    if (strcmp(runway_in_use, "CLOSED"))
      printf(" ACTIVE    FALSE \n");   else
      printf(" ACTIVE    TRUE \n");

Это мой первый ответ на 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;
            }
        }
    }
}

Я бы сказал, что это плохо.

while (!b) {
    // do something 
}

читается гораздо лучше, чем

while (b != true) {
    // do something 
}

одна из причин, по которой первый (B==false) неодобрительно относится к тому, что новички часто не понимают, что вторая альтернатива (!Б) возможно вообще. Таким образом, использование первой формы может указывать на неправильное представление с булевыми выражениями и булевыми переменными. Таким образом, использование второй формы стало своего рода sjiboleth: когда кто-то пишет это, он/она, вероятно, понимает, что происходит.

Я считаю, что это привело к тому, что разница считается более важной чем на самом деле.