Quebra de linha antes / depois do operador [fechado]

29

Enquanto a convenção de código Java da Sun sugere colocar a quebra de linha diante do operador, muitas outras diretrizes discordam dela. Não vejo prós e contras óbvios, então há vantagens em usar um desses estilos em detrimento de outro?

String longVarName = a + b + c + d +
          e + f;

vs

String longVarName = a + b + c + d
          + e + f;
Nutel
fonte
Você pode postar um exemplo de código simples mostrando as duas convenções?
Michael
Primeiro, tentaria evitar a situação usando algo como isto: download.oracle.com/javase/1.4.2/docs/api/java/lang/…
Job
O link está quebrado.
Florian F

Respostas:

14

Eu o deixaria em uma linha e, em vez disso, pensaria na legibilidade em termos de nomes (e funções) de variáveis ​​que revelam a intenção.

Quando ficar confuso, é hora de refatorar :

  • renomear vars
  • introduzir novos vars / funções

Exemplo

subtotal = price * (100 + tax_ratio) / 100`

vs.

tax = price * tax_ratio / 100
subtotal = price + tax
Kamil Tomšík
fonte
2
A fórmula à esquerda está incorreta. Deve ser um price * (100 + tax_ratio) / 100ou apenas price * (1 + tax_ratio), dependendo se tax_ratioé em porcentagem ou fracionário.
Rufflewind
4
Isso não responde à pergunta. Deve haver uma lei contra esse tipo de resposta.
Edward D'Souza
@ EdwardD'Souza Eu sinto o mesmo. Mas por que a resposta foi aceita?
Rudy Vissers
@RudyVissers a resposta resolve o problema em um nível mais profundo. Ele resolve o problema da necessidade de quebra de linha em primeiro lugar. Nessa perspectiva, o OP poderia considerá-lo uma resposta para o seu problema, mas ainda não é apropriado da perspectiva de ser um wiki da comunidade.
Edward D'Souza
ei, eu não estou mais por aqui, mas é realmente simples - se você se encontra nessa situação, provavelmente está fazendo algo errado e deve pensar em refatorar o código - ou, em outras palavras, depois de 15 anos de programação. simplesmente não me importo mais com essas coisas, o que me importa é a clareza, a simplicidade do código e a facilidade para que outras pessoas me ajudem
Kamil Tomšík
36

Eu posso imaginar legibilidade sendo um argumento

result = longidentifier +
   short -
   alittlelonger -
   c;

versus

result = longidentifier
   + short
   - alittlelonger
   - c;

No segundo exemplo, os operadores estão bem alinhados e você pode ver facilmente com qual sinal a variável entra na equação. Eu acho que isso também faz sentido para operadores binários, mas com o suporte etc., você deve fazer o que for mais claro.

Otto Allmendinger
fonte
4
Para situações em que os operadores são importantes (como expressões matemáticas e outras), eu escolheria o número dois, porque, como você disse, é muito mais legível. Mas para strings eu escolheria as primeiras opções, pois os operadores são "sem sentido". Eles não fazem nada além de juntar as strings e, como as strings são importantes, eu preferiria as primeiras opções.
Niklas H
Ambos os casos têm mérito. Ambos os casos são melhores do que colocar tudo em uma fila muito longa! Minha preferência é usar um suporte de abertura no início (mesmo que não seja necessário) e, em seguida, ter tudo alinhado com isso. Isso torna muito mais óbvio.
quickly_now
35

Normalmente, sigo as diretrizes de estilo mais usadas ou algumas ferramentas padrão de codificação. A vantagem de usar um estilo comumente usado traz benefícios quando você está lendo o código de outras pessoas ou envolvido em um projeto de código aberto, no qual são definidas diretrizes de estilo.

Os estilos mais comuns que eu já vi é o segundo estilo da pergunta. Veja abaixo a lista deles:

Guia de estilo do Google :

Quando uma linha é interrompida em um operador que não é de atribuição, a quebra ocorre antes do símbolo.

Convenção de codificação solar :

Quebre antes de um operador

O valor padrão da verificação Wrap Wrap do operador Checkstyle é nl:

O operador deve estar em uma nova linha

ceilfors
fonte
2
Atualizei minha resposta por uma questão de clareza + Convenção de codificação da Sun.
ceilfors
google.github.io/styleguide/javaguide.html (link na resposta é quebrado)
Martin Pfeffer
10

No código, costumo colocar o intervalo após o operador:

foo = some_long_expression() +
      some_other_long_expression();

Aqui, esse operador pendente no final de uma linha é uma grande pista para o leitor de que o código continua. Em idiomas que não possuem terminadores de instrução, esse operador dangling pode servir como uma pista suficiente para o compilador / intérprete de que o código continua (caso contrário, eu precisaria usar alguma construção feia de linha de continuação).

Ao documentar essa expressão (se precisar de documentação), costumo colocar a interrupção diante do operador.

David Hammen
fonte
Pelo menos algumas linguagens (por exemplo, Python) não aceitam um operador binário à direita como sugestão de que a linha continua, mas exige mais. Observe que as novas linhas dentro de parênteses geralmente não são contadas; portanto, você não precisa de um caractere de continuação de linha explícito (e propenso a erros).
3

Contanto que você permaneça consistente, saiba que não há nenhuma vantagem real de qualquer maneira. Isso é especialmente importante quando se considera mesclagem de código e espaço em branco.

Martijn Verburg
fonte
3

Acredito que a linha deve começar com o símbolo mais alto na árvore de análise da instrução que você deseja quebrar. Destaca o operador que é mais importante na expressão. É a mesma razão pela qual você coloca um outro no início de uma linha e não no final da linha anterior.

No exemplo a seguir, varrendo a margem esquerda, você vê a estrutura da instrução como um OR de 3 expressões.

if (ch>='A' && ch<='Z'
    || ch>='a' && ch<='z'
    || ch>='0' && ch<='9')
{...}

Abaixo, o || operadores são menos destacados. É menos óbvio que é um || de expressões. Especialmente se as linhas tiverem comprimentos diferentes.

if (ch>='A' && ch<='Z' ||
    ch>='a' && ch<='z' ||
    ch>='0' && ch<='9')
{...}

E apenas para referência, isso é muito errado. O || operadores não são destacados.

if ( ch>='A' && ch<='Z' || ch>='a'
     && ch<='z' || ch>='0' && ch<='9')
{...}

Eu até gosto de colocar vírgulas no início da linha, mesmo que raramente veja isso. Abstendo-me de fazer isso no código compartilhado.

var note:Object =
    { key: key
    , type: 'P'
    , text: someLongProcedureCallGettingTheUserInitials()
       + ": " + getTheTextThatWasTyped()
    };
Florian F
fonte
2

Para longas equações aritméticas, normalmente faço uma de duas coisas.

deixe tudo em uma única linha:

foo = bar + baz - fizz + buzz + alpha - beta;

Normalmente faço isso para equações que contêm apenas adição e subtração, acho muito fácil digitar erros de multiplicação e divisão que podem atrapalhar seriamente o escopo do operador.

o segundo formato que eu uso são operadores progressivos:

foo = bar;
foo += baz;
foo -= fizz;
foo += buzz;
foo /= alpha - beta;
foo *= spiff;

Não vejo razão para reduzi-lo para uma única linha, a menos que se prove que melhora o desempenho de maneira perceptível. Além disso, não há ambiguidade do que está acontecendo, e há menos chances de colocar um parêntese nos operadores /e *.

zzzzBov
fonte
2

Colocar o caractere de concatenação (ou qualquer operador) no início da linha melhora a legibilidade. Nós digitalizamos o código focando no início de cada linha. Quando uma linha começa com um operador, o leitor pode dizer que a linha é uma continuação da instrução anterior, digitalizando esse caractere.

Expressões matemáticas longas são sempre digitadas para que cada nova linha comece com um operador. Não há razão para que o código não deva seguir esta convenção.

Kevin Cline
fonte
0

Deixe a expressão em uma linha e, se ficar muito longa, divida-a em expressões menores:

days = ((year * months_per_year) + month) * days_per_month + day

torna-se:

months = year * months_per_year + month
days = months * days_per_month + day

Se isso não for possível, acho mais legível interromper o operador e fazer com que o operador comece diretamente abaixo da tarefa anterior (colocá-la abaixo da variável me faz pensar e ser mais recente, o que é chato, pois o objetivo é é facilitar a leitura):

random = years * months_per_year 
         + month * days_per_month 
         + day * hours_per_day 
         + hour * minutes_per_hour 
         + minute * seconds_per_minute 
         + second
Joel
fonte
1
Esta resposta não adiciona nada de novo ao que já foi dito.
Martijn Pieters