Por que usar! boolean_variable Acima boolean_variable == false

55

Um comentário sobre esta questão: Verificando se um método retorna falso: atribuir resultado a variável temporária ou colocar chamada de método diretamente em condicional? diz que você deve usar !boolean em vez de boolean == false ao testar condições. Por quê? Para mim, boolean == false é muito mais natural em inglês e é mais explícito. Peço desculpas se isso é apenas uma questão de estilo, mas fiquei me perguntando se havia algum outro motivo para essa preferência de !boolean ?

    
por ell 12.04.2017 / 09:31
fonte

16 respostas

148

Quando vejo uma linha como if (!lateForMeeting()) , leio isso como "Se não atrasar para a reunião" , o que é bastante simples de entender, ao contrário de if (lateForMeeting() == false) que eu d ler como "Se o fato de estar atrasado para a reunião for falso" .

Eles têm um significado idêntico, mas o primeiro está mais próximo de como a sentença inglesa equivalente seria construída.

    
por 26.02.2012 / 06:13
fonte
96

Escrever == false e == true é redundante. Pode ser levado a extremos arbitrários também. Se você começar a escrever

if (condition == false) { ... }

Então por que não

if ((condition == false) == true) { ... }

Ou porque não

if ((someExp == anotherExp) == true) { ... }

A moral dessa história é que, se condition for uma expressão booleana, não será necessário adicionar == false ; é para isso que o operador ! é para;)

    
por 25.02.2012 / 22:37
fonte
70

Em C e em alguns idiomas semelhantes, comparar expressões booleanas para igualdade com false ou true é um hábito perigoso.

Em C, qualquer expressão escalar (numérica ou ponteiro) pode ser usada em um contexto booleano, por exemplo, como a condição de uma instrução if . A regra C é que if (cond) é equivalente a if (cond != 0) - ou seja, zero é falso e qualquer valor diferente de zero é verdadeiro. Se cond for do tipo de ponteiro, 0 será tratado como uma constante de ponteiro nulo; if (ptr) significa if (ptr != NULL) .

Isso significa que

if (cond)

e

if (cond == true)

não significa a mesma coisa . O primeiro é verdadeiro se cond for diferente de zero; o segundo é verdadeiro apenas se for igual a true , que em C (se você tiver #include <stdbool.h> ) é simplesmente 1 .

Por exemplo, a função isdigit() declarada em <ctype.h> retorna um valor int , 0 se o argumento for um dígito, diferente de zero se não for. Pode retornar 42 para indicar que a condição é verdadeira. A comparação de 42 == true falhará.

Acontece que 0 é o único valor considerado falso, portanto, a comparação de igualdade para false funcionará; if (!cond) e if (cond == false) fazem a mesma coisa. Mas se você vai tirar proveito disso, você tem que lembrar que comparando com false está ok, e comparando com true não está. Pior ainda, comparar com true funcionará na maior parte do tempo (por exemplo, os operadores de igualdade e relacional sempre geram 0 ou 1 ). Isso significa que quaisquer erros que você introduzir usando isso ainda podem ser difíceis de rastrear. (Não se preocupe, eles aparecerão assim que você demonstrar o código para um cliente importante.)

C ++ tem regras ligeiramente diferentes; por exemplo, seu tipo bool é um pouco mais integrado ao idioma e if (cond) converte cond para tipo bool . Mas o efeito é (principalmente) o mesmo.

Algumas outras linguagens têm o que se pode chamar de booleanos de melhor comportamento, de modo que cond == true e cond == false (ou seja qual for a sintaxe) é seguro. Mesmo assim, cada idioma que vi tem um operador not ou ! ; está lá, então você também pode usá-lo. Usar cond == false em vez de !cond ou not cond , na minha opinião, não melhora a legibilidade. (É verdade que o caractere ! pode ser difícil de ver de relance; às vezes, adiciono um espaço após o ! para evitar isso.)

E muitas vezes você pode evitar o problema e melhorar a clareza reorganizando o código um pouco. Por exemplo, em vez de:

if (!cond) {
    do_this();
}
else {
    do_that();
}

você pode escrever:

if (cond) {
     do_that();
}
else {
    do_this();
}

Isso não é sempre melhor, mas não custa procurar oportunidades onde está.

Resumo: Em C e C ++, as comparações de igualdade com true e false são perigosas, excessivamente detalhadas e pobres. Em muitos outros idiomas, essas comparações podem não ser perigosas, mas ainda são excessivamente verbosas e pobres.

    
por 26.02.2012 / 00:32
fonte
13

Se condition == false é de fato "muito mais natural em inglês" para você, devo assumir que você não é um falante nativo. Caso contrário, não posso explicar isso, porque nobody fala assim:

If the sun is shining is false I stay at home.

Compare isso com

If the sun is not shining I stay at home.

Dito isso, concordo que o caractere ! simples e delgado é facilmente ignorado no código. Por esse motivo, prefiro a palavra-chave not quando suportada pelo idioma. C ++, por exemplo, faz permitir isso, embora muitos programadores não estejam cientes disso.

Para idiomas que exigem ! , coloco um espaço entre operador e operando. Isso torna a negação muito mais difícil de ignorar:

if (! condition) { … }

Observe que todo programador deve traduzir isso automaticamente , sem pensar duas vezes, para "não condicionar" em sua mente. Adquirir esse tipo de fluência na leitura de expressões de código está entre os primeiros passos para se tornar um bom programador.

    
por 27.02.2012 / 02:07
fonte
13

Os dois são funcionalmente idênticos, então qual deles é uma questão de gosto.

A principal razão pela qual eu uso == false é que descobri que ! é muito fácil de ignorar quando se olha para o código.

Tendo sido mordido severamente por isso, criei o hábito de deixar isso bem claro ao testar falsas.

Se o operador tivesse sido nomeado not como em Pascal, não acho que isso teria se tornado um problema.

    
por 06.03.2012 / 16:19
fonte
7

Quando vejo var == false , sempre me pergunto se var é booleano ou de um tipo lógico com mais de dois valores (com, por exemplo, maybe e undefined , bem como true e false , ou algo como os nove valores do IEEE 1164 ).

    
por 21.11.2012 / 17:54
fonte
6

porque às vezes você pode escrever boolean = false (com os erros óbvios) e false == boolean não parece natural (não importa quão boa seja a prática)

    
por 25.02.2012 / 21:51
fonte
4

if (!boolean_variable) traduz a if the condition is not true .

if (boolean == false) traduz a if the condition not false is true . Porque isso é lógica inversa, é mais difícil de entender.

    
por 26.02.2012 / 12:56
fonte
2

Em (muito) compiladores mais antigos, acredito que eles quebrariam (boolean == false) em 2 atribuições de registro e um código de comparação em linguagem de máquina. O primeiro exemplo seria dividido em uma atribuição e um operador NOT. Em termos de desempenho, a operação de comparação levaria vários ciclos de clock, dependendo do tamanho do registrador sendo comparado, comparado a um invertido bit a bit (1 clock) e seria mais lento para executar.

Dito isso, acredito que os compiladores mais novos acabam com isso, então deve ser OK ir com qualquer um deles.

    
por 26.02.2012 / 05:39
fonte
1

No trabalho, muitas vezes estou lidando com booleanos que podem ser nulos, então geralmente codifico este caso como

if (value != null && value == true){
    //do something
}

porque eu pessoalmente sinto que a simetria facilita a leitura. Especialmente se houver outros booleanos sendo testados também.

Eu realmente não me importo de uma forma ou de outra.

    
por 25.02.2012 / 21:52
fonte
1

Quando você está testando a verdadeira condição, faz sentido fazer apenas if (condition) , especialmente quando você aplica a convenção de nomear variáveis booleanas começando com 'is': if (isOpen) é perfeitamente claro e usando != false ser redundante.

Para um C / C ++ / Java / etc. programador, o significado do '!' O operador é completamente assimilado, a ponto de termos automaticamente "não" em nossas mentes quando o vemos. Então, ter if (!isOpen) é tão claro quanto if (_NOT_ isOpen) para mim. Mas você não está familiarizado o suficiente, em C / C ++ você pode criar uma macro com #define _NOT_ ! . Mas confie em mim, depois de alguns anos isso é completamente desnecessário.

Além disso, é sempre preferível testar valores booleanos sem compará-los com literais. Por exemplo, é perigoso testar if (x == true) porque um valor booleano é considerado verdadeiro se não for zero, e o literal tem apenas um valor específico, então x pode ser 'verdadeiro' (ou seja, diferente de zero) e ainda a comparação é avaliada como falsa (porque contém 2 e o literal verdadeiro é, digamos, 1.) Claro que isso não se aplica a uma comparação com false, mas se você não usá-lo ao testar true, por que usá-lo ao testar false?

    
por 25.02.2012 / 23:16
fonte
0

O tamanho é importante;)

Em expressões mistas, é mais fácil de ler:

boolean1 = false
boolean2 = true

p ! boolean1 and ! boolean2
p boolean1 == false and boolean2 == false

E especial para ruby um exemplo onde é uma grande diferença:

boolean = nil
p ! boolean         #-> true
p boolean == false  #-> false

nada é falso, mas também não é verdade.

    
por 25.02.2012 / 22:09
fonte
0

Com base na minha experiência e nas respostas da minha pergunta à qual você se vinculou.

Algumas pessoas preferem usar if (condição), porque o motivo é que é mais curto para escrever. e para mim, na verdade, faz sentido, por exemplo (! isValidated ()) eu li isso como não validado. mas para mim é tudo baseado em preferências pessoais, e isso depende da estrutura lógica do método isValidated (), se ele retorna true ou false

    
por 26.02.2012 / 07:47
fonte
0

Se você nomeou sua variável corretamente, então !boolean é mais natural. Ele lê como not boolean para qualquer um que seja um programador suficiente para ler o código mentalmente.

    
por 26.02.2012 / 14:02
fonte
0

Para algumas pessoas, quanto mais cedo um significado for expresso, melhor.

Para aqueles que têm "se! ..." comparam-se mais rápido a "se ..." então precisam ler toda a condição (que pode ser bem longa, por exemplo (thisThing = thatThing ou alguma coisa = a outra coisa) ) OR (coisa = coisab e coisa = coisad), etc.) apenas para encontrar o == falso no final.

Tendo o! (Eu realmente prefiro não quando a linguagem permite) na frente recebe o Inglês 'não' para essa condição lá mais cedo.

Esse problema também leva em consideração o uso de until nos idiomas que o suportam, por exemplo, faça 'coisas comuns' até que a coisa termine. Como outros dizem, a expressão da linguagem natural é o objetivo. Eu gosto do exemplo do "sol está brilhando" acima.

    
por 27.02.2012 / 05:53
fonte
0

Outra razão é que, se você está trabalhando em uma base de código que usa vários idiomas, se há uma maneira idiomática de fazer algo seguro em todos os idiomas, é uma boa ideia fazer isso em todos os lugares para que você forme um bom hábito e são menos propensos a tropeçar.

Não consigo pensar em nenhum lugar em que if (!variable) (ou equivalentes como if not variable dependendo do seu idioma) não seja seguro, enquanto, por exemplo, if self.is_ready() == False: ... não é seguro em python se self.is_ready() retornar None , agora ou no futuro, o que seria uma coisa totalmente razoável para indicar que não estava pronto, pois None é tão false quanto False .

    
por 08.10.2018 / 15:32
fonte