É uma prática ruim usar uma declaração if sem chaves? [fechadas]


130

Eu vi código assim:

if(statement)
    do this;
else
    do this;

No entanto, acho que isso é mais legível:

if(statement){
    do this;
}else{
    do this;
}

Como os dois métodos funcionam, isso é simplesmente uma questão de preferência a ser usada ou de uma maneira recomendada em relação à outra?



Na minha opinião, é ruim, porque você começa a confiar na indentação de espaço em branco que quase nunca é totalmente consistente. Isso inviabiliza a linha de pensamento do leitor quando eles precisam se preocupar com essas coisas.
Sridhar Sarnobat

Respostas:


212

O problema com a primeira versão é que, se você voltar e adicionar uma segunda instrução às cláusulas if or else sem se lembrar de adicionar os chavetas, seu código será quebrado de maneiras inesperadas e divertidas.

Em termos de manutenção, é sempre mais inteligente usar o segundo formulário.

EDIT: Ned aponta isso nos comentários, mas vale a pena vincular aqui também, eu acho. Esta não é apenas uma besteira hipotética da torre de marfim: https://www.imperialviolet.org/2014/02/22/applebug.html


17
E você deve sempre codificar para manutenção. Afinal, tenho certeza de que o compilador não se importa com o formulário que você usa. Seus colegas de trabalho, no entanto, podem ser perigosos se você introduzir um bug devido a um erro bobo de chaves.
Esteban Araya

12
Ou você poderia usar uma linguagem que não usa suportes para blocos de código ...
Tor Valamo

10
@ lins314159 - Não, quero dizer, como python. Porque sou chauvinista a esse respeito.
Tor Valamo

17
Outros erros de prova podem (e acontecem): imperialviolet.org/2014/02/22/applebug.html
Ned

8
Afirmar que o bug do SSL é um argumento a favor de chaves é falso. Não é como se o desenvolvedor pretendesse escrever, if (…) { goto L; goto L; }mas esquecesse o aparelho. É pura coincidência que `` if (…) {goto L; vá para L; } `passa a não ser um bug de segurança, porque ainda é um bug (mas não com conseqüências de segurança). Em outro exemplo, as coisas podem ir na direção oposta e o código sem pulseira pode ser acidentalmente seguro. Em um terceiro exemplo, o código sem pulseira seria livre de erros inicialmente e o desenvolvedor introduziria um erro de digitação ao adicionar os aparelhos.
Pascal Cuoq

112

Um problema em deixar de fora os blocos de instruções é a outra ambiguidade. As linguagens inspiradas em C ignoram o recuo e, portanto, não têm como separar isso:

if(one)
    if(two)
        foo();
    else
        bar();

Disto:

if(one)
    if(two)
        foo();
else
    bar();

8
Esse é um problema muito mais sério do que o mencionado na resposta superior (adicionando uma segunda declaração).

3
de fato, essa resposta me levou de ler cinicamente essas respostas a estar levemente preocupada. Eu posso ter cometido esse erro.
omikes

2
Se alguém mais estava se perguntando como eu era o modo como C realmente o interpreta, um teste que fiz com o GCC interpreta esse código da primeira maneira. tpcg.io/NIYeqx
horta

2
"ambiguidade" é o termo errado. Não há ambiguidade alguma em como o analisador verá isso: o elsevínculo avidamente ao mais próximo e mais interno if. O problema surge quando C ou linguagens semelhantes estão sendo codificadas por pessoas que não sabem disso, não pensam ou ainda não têm café suficiente - então elas escrevem códigos que acham que farão uma coisa, mas o A especificação de idioma diz que o analisador precisa fazer outra coisa, que pode ser muito diferente. E sim, esse é outro argumento sólido em favor de sempre incluir chaves, mesmo que a gramática as sinalize como teoricamente "desnecessárias".
Underscore_d

35

Meu padrão geral é que, se ele se encaixar em uma linha, eu faço:

if(true) do_something();

Se houver uma cláusula else, ou se o código no qual eu quero executar truefor de tamanho significativo, use chaves:

if(true) {
    do_something_and_pass_arguments_to_it(argument1, argument2, argument3);
}

if(false) {
    do_something();
} else {
    do_something_else();
}

Em última análise, tudo se resume a uma questão subjetiva de estilo e legibilidade. O mundo da programação geral, no entanto, se divide em duas partes (para linguagens que usam chaves): use-as o tempo todo, sem exceção, ou use-as o tempo todo, com exceção. Eu faço parte do último grupo.


4
Embora, por mais fácil que seja escrever if(true){ do_something(); }, por que arriscar que outro programador introduza um bug sério no caminho (procure a falha total do código SSL da Apple "goto fail").
28815 Craig

9
Nenhuma quantidade de colchetes liberará o mantenedor de usar seu cérebro. Eu apoio a idéia de "sem colchetes, se ele se encaixar em uma linha", porque, bem, para mim, esse é um código if , que é apenas uma versão do operador if ternário, no qual não é necessário fazer nada na parte "after:" ternário. E por que alguém introduziria colchetes no ternário se ?
Michal M

Não concordo de modo algum que, em última análise, seja subjetivo, nem que apenas afete o estilo e a legibilidade. Como alguém que perdeu tempo tentando depurar problemas que resultou, foram causados ​​por falta de delimitadores de bloco (e não percebeu sua ausência), porque eu tive que usar um estilo de codificação que os omitia quando 'desnecessário' - e que leu sobre vários erros terríveis causados ​​por esses estilos de codificação - acho que essa é uma questão prática e muito objetiva. Certamente, com um estilo exigindo delimitadores, ainda podemos esquecê-los, mas certamente - pelo menos - a memória muscular nos torna muito menos propensos a isso.
underscore_d

10

Estou usando o formatador de código do IDE que uso. Isso pode ser diferente, mas pode ser configurado nas Preferências / Opções.

Eu gosto deste:

if (statement)
{
    // comment to denote in words the case
    do this;
    // keep this block simple, if more than 10-15 lines needed, I add a function for it
}
else
{
    do this;
}

5
Sendo esta uma questão de estilo inteiramente subjetiva, eu pessoalmente não gosto da redundância das linhas apenas de chaves. Mas ei.
Matchu

14
Eu apoio esse estilo. A maioria das pessoas lê o código da esquerda para a direita e isso meio que faz com que nossos olhos fiquem ancorados na borda esquerda da tela. Ajuda a separar e extrair visualmente o código para blocos lógicos de etapas.
mloskot

6
Eu sempre preferi esse estilo. Muito mais fácil encontrar o parêntese de fechamento correspondente. Então, é preciso muito espaço? Use uma fonte menor.
timday

4
Eu sempre acho mais fácil "varrer" o código quando as chaves estão em linhas separadas. Isso vale para tudo; classes, métodos, declarações if e while, etc. Nunca gostei de ter que primeiro cinta na mesma linha ...
Svish

2
Espaço em branco é barato, especialmente quando você tem um IDE capaz de dobrar códigos.
Moo

10

A "regra" que sigo é a seguinte:

Se a instrução "if" estiver sendo testada para fazer alguma coisa (funções de chamada do IE, configurar variáveis ​​etc.), use chaves.

if($test)
{
    doSomething();
}

Isso ocorre porque eu sinto que você precisa deixar claro quais funções estão sendo chamadas e para onde está indo o fluxo do programa, em que condições. Fazer com que o programador entenda exatamente quais funções são chamadas e quais variáveis ​​são definidas nessa condição é importante para ajudá-lo a entender exatamente o que seu programa está fazendo.

Se a instrução "if" estiver testando para parar de fazer algo (controle de fluxo do IE dentro de um loop ou função), use uma única linha.

if($test) continue;
if($test) break;
if($test) return;

Nesse caso, o importante para o programador é descobrir rapidamente quais são os casos excepcionais em que você não deseja que o código seja executado, e tudo isso é coberto em $ test, não no bloco de execução.


8

Ter o aparelho certo desde o primeiro momento deve ajudar a impedir que você precise depurar isso:

if (statement)
     do this;
else
     do this;
     do that;

1
Essa parece ser a lógica aceita, mas (para interpretar o advogado do diabo aqui) uma única regra adicional de realce de sintaxe também não resolveria isso, ao salvar uma linha?
Ken

2
O mesmo acontece com um IDE que corrige o recuo quando você ;
clica em

6

Use chaves para todas as declarações if, mesmo as mais simples. Ou, reescreva uma instrução if simples para usar o operador ternário:

if (someFlag) {
 someVar= 'someVal1';
} else {
 someVar= 'someVal2';
}

Parece muito melhor assim:

someVar= someFlag ? 'someVal1' : 'someVal2';

Mas use o operador ternário apenas se tiver certeza absoluta de que não há mais nada a ser inserido nos blocos if / else!



2

Pela minha experiência, a única (muito) pequena vantagem do primeiro formulário é a legibilidade do código, o segundo formulário adiciona "ruído".

Mas, com os IDEs modernos e a geração automática de código (ou o preenchimento automático), recomendo fortemente o uso do segundo formulário, você não gastará tempo extra digitando chaves e evitará alguns dos erros mais frequentes.

Existem bugs de consumo de energia suficientes, as pessoas simplesmente não abrem as portas por grandes perdas de tempo.

Uma das regras mais importantes a serem lembradas ao escrever código é a consistência. Toda linha de código deve ser escrita da mesma maneira, independentemente de quem a escreveu. Ser rigoroso impede que bugs "aconteçam";)

O mesmo ocorre com a nomeação clara e explícita de suas variáveis, métodos, arquivos ou com a identificação correta deles ...

Quando meus alunos aceitam esse fato, eles param de lutar contra seu próprio código-fonte e passam a ver a codificação como uma atividade realmente interessante, estimulante e criativa. Eles desafiam suas mentes, não seus nervos!


2

É uma questão de preferência. Eu pessoalmente uso os dois estilos, se tiver certeza razoável de que não precisarei adicionar mais instruções, utilizarei o primeiro estilo, mas, se possível, utilizarei o segundo. Como você não pode adicionar mais instruções ao primeiro estilo, ouvi algumas pessoas recomendarem não usá-lo. No entanto, o segundo método incorre em uma linha adicional de código e se você (ou seu projeto) usa esse tipo de estilo de codificação, o primeiro método é muito preferido para instruções if simples:

if(statement)
{
    do this;
}
else
{
    do this;
}

No entanto, acho que a melhor solução para esse problema está no Python. Com a estrutura de blocos baseada em espaço em branco, você não tem dois métodos diferentes para criar uma instrução if: você só tem um:

if statement:
    do this
else:
    do this

Embora isso tenha o "problema" de que você não pode usar os aparelhos, você ganha o benefício de que não há mais linhas que o primeiro estilo e que tem o poder de adicionar mais instruções.


Eu por mim acho que a maneira como alças Python if-else declarações é muito feio, mas, novamente, não sou programador Python (ainda)
helpermethod

1

Eu sempre tentei tornar meu código padrão e parecer o mais próximo possível. Isso facilita que outras pessoas o leiam quando estão encarregados de atualizá-lo. Se você der o seu primeiro exemplo e adicionar uma linha no meio, ela falhará.

Não vai funcionar:

if (declaração) faz isso; e isto; mais faça isso;


1

Pessoalmente, eu uso o primeiro estilo apenas para lançar uma exceção ou retornar prematuramente de um método. Como argumento Verificação no início de uma função, porque nesses casos, raramente tenho mais do que uma coisa a fazer e nunca há outra.

Exemplo:

if (argument == null)
    throw new ArgumentNullException("argument");

if (argument < 0)
    return false;

Caso contrário, eu uso o segundo estilo.


1

Minha preferência pessoal é usar uma mistura de espaços em branco e colchetes como este:

if( statement ) {

    // let's do this

} else {

    // well that sucks

}

Eu acho que isso parece limpo e torna meu código muito fácil de ler e mais importante - depurar.


0

Concordo com a maioria das respostas no fato de que é melhor ser explícito no seu código e usar chaves. Pessoalmente, adotaria um conjunto de padrões de codificação e garantiria que todos na equipe os conhecessem e se conformassem. Onde trabalho, usamos os padrões de codificação publicados pelo IDesign.net para projetos .NET.


0

Eu prefiro colocar uma chave. Mas, às vezes, o operador ternário ajuda.

Ao invés de :

int x = 0;
if (condition) {
    x = 30;
} else {
    x = 10;
}

Deve-se simplesmente fazer: int x = condition ? 30 : 20;

Imagine também um caso:

if (condition)
    x = 30;
else if (condition1)
    x = 10;
else if (condition2)
    x = 20;

Seria muito melhor se você colocar a chave.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.