Salto de línea antes / después del operador [cerrado]

29

Si bien la convención de código Java de Sun sugiere poner un salto de línea antes que el operador, muchas otras pautas no están de acuerdo con él. No veo ningún pros y contras obvios, entonces, ¿hay ventajas de usar uno de estos estilos sobre otro?

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

vs

String longVarName = a + b + c + d
          + e + f;
Nutel
fuente
¿Puedes publicar un ejemplo de código simple que muestre ambas convenciones?
Michael
Primero trataría de evitar la situación usando algo como esto: download.oracle.com/javase/1.4.2/docs/api/java/lang/…
Job
El enlace está roto.
Florian F

Respuestas:

14

Lo dejaría en una línea y más bien pensaría en la legibilidad en términos de nombres de variables (y funciones) que revelen la intención.

Una vez que se vuelve desordenado, es hora de refactorizar :

  • renombrar vars
  • introducir nuevos vars / funciones

Ejemplo

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

vs.

tax = price * tax_ratio / 100
subtotal = price + tax
Kamil Tomšík
fuente
2
La fórmula de la izquierda es incorrecta. Debe ser price * (100 + tax_ratio) / 100o solo price * (1 + tax_ratio), dependiendo de si tax_ratioes en porcentaje o fraccional.
Rufflewind
44
Esto no responde la pregunta. Debería haber una ley contra este tipo de respuestas.
Edward D'Souza
@ EdwardD'Souza Siento lo mismo. Pero, ¿por qué se aceptó la respuesta?
Rudy Vissers
@RudyVissers la respuesta resuelve el problema a un nivel más profundo. Resuelve el problema de la necesidad de un salto de línea en primer lugar. Desde esa perspectiva, el OP podría considerarlo una respuesta a su problema, pero aún así no es apropiado desde la perspectiva de que sea una wiki comunitaria.
Edward D'Souza
oye, ya no estoy por aquí, pero es realmente simple: si te encuentras en tal situación, probablemente lo estés haciendo mal y deberías pensar en refactorizar el código, o decirlo de otra manera, después de 15 años de programación. simplemente ya no me importan esas cosas, lo que sí me importa es la claridad del código, la simplicidad y facilitar que otras personas me ayuden
Kamil Tomšík
36

Me imagino que la legibilidad es un argumento

result = longidentifier +
   short -
   alittlelonger -
   c;

versus

result = longidentifier
   + short
   - alittlelonger
   - c;

En el segundo ejemplo, los operadores están bien alineados y puede ver fácilmente con qué signo entra la variable en la ecuación. Creo que esto también tiene sentido para los operadores binarios, pero con arriostramiento, etc., debe hacer lo que sea más claro.

Otto Allmendinger
fuente
44
Para situaciones en las que los operadores son importantes (como las expresiones matemáticas y demás), elegiría el número dos porque, como dijiste, es mucho más legible. Pero para cadenas elegiría las primeras opciones, ya que los operadores son "sin sentido". No hacen nada más que unir cadenas y, dado que las cadenas son lo más importante, preferiría las primeras opciones.
Niklas H
Ambos casos tienen mérito. ¡Ambos casos son mejores que poner todo en una línea muy larga! Mi preferencia es usar un soporte de apertura al inicio (aunque no sea necesario) y luego tener todo alineado debajo de eso. Lo hace mucho más obvio.
rapid_now
35

Normalmente sigo las pautas de estilo más utilizadas o ciertas herramientas estándar de codificación. La ventaja de usar un estilo de uso común trae beneficios cuando lee el código de otras personas o participa en un proyecto de código abierto donde se establecen pautas de estilo.

Los estilos más comunes que he visto es el segundo estilo en la pregunta. Vea a continuación la lista de ellos:

Guía de estilo de Google :

Cuando se rompe una línea en un operador sin asignación, la ruptura aparece antes del símbolo.

Convención de codificación solar :

Romper ante un operador

El valor predeterminado de Checkstyle Operator Wrap check es nl:

El operador debe estar en una nueva línea.

techos
fuente
2
Actualicé mi respuesta para mayor claridad + convención de codificación de Sun.
ceilfors
google.github.io/styleguide/javaguide.html (el enlace en la respuesta está roto)
Martin Pfeffer
10

En el código, tiendo a poner el descanso después del operador:

foo = some_long_expression() +
      some_other_long_expression();

Aquí ese operador que cuelga al final de una línea es una gran pista para el lector de que el código continúa. En los lenguajes que no tienen terminadores de enunciados, ese operador colgante puede servir como una pista suficiente para el compilador / intérprete de que el código continúa (de lo contrario, tendría que usar alguna construcción de línea de continuación fea).

Al documentar esa expresión (si necesita documentación), tiendo a poner el salto antes que el operador.

David Hammen
fuente
Al menos algunos lenguajes (p. Ej., Python) no toman un operador binario final como pista de que la línea continúa pero requieren más. Tenga en cuenta que las líneas nuevas dentro de parens generalmente no se cuentan, por lo que no necesita un carácter de continuación de línea explícita (y propensa a errores).
3

Mientras permanezca constante, sepa que no hay una ventaja real de ninguna manera. Esto es especialmente importante cuando se consideran fusiones de código y espacios en blanco.

Martijn Verburg
fuente
3

Creo que la línea debe comenzar con el símbolo más alto en el árbol de análisis de la declaración que desea romper. Destaca el operador que es más importante en la expresión. Es la misma razón por la que pones otro más al comienzo de una línea y no al final de la línea anterior.

En el siguiente ejemplo, al escanear el margen izquierdo, verá la estructura de la declaración como un OR de 3 expresiones.

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

Debajo, el || los operadores están menos resaltados. Es menos obvio que es un || de expresiones Especialmente si las líneas eran de diferentes longitudes.

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

Y solo como referencia, esto está muy mal. El || los operadores no están resaltados en absoluto.

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

Incluso me gusta poner comas al comienzo de la línea, aunque rara vez lo veo. Me abstengo de hacer eso en código compartido.

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

Para ecuaciones aritméticas largas, típicamente hago una de dos cosas.

Deje todo en una sola línea:

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

Normalmente hago esto para ecuaciones que contienen solo sumas y restas, me resulta muy fácil hacer un error tipográfico con multiplicación y división que puede dañar seriamente el alcance del operador.

El segundo formato que uso es operadores progresivos:

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

No veo ninguna razón para acortarlo a una sola línea, a menos que pueda demostrarse que mejora el rendimiento de manera notable. Además, no hay ambigüedad de lo que está sucediendo y dónde, y hay menos posibilidades de extraviar un paréntesis para los operadores /y *.

zzzzBov
fuente
2

Colocar el carácter de concatenación (o cualquier operador) al comienzo de la línea mejora la legibilidad. Escaneamos código enfocándonos en el comienzo de cada línea. Cuando una línea comienza con un operador, el lector puede decir que la línea es una continuación de la declaración anterior al escanear ese carácter.

Las expresiones matemáticas largas siempre se componen para que cada nueva línea comience con un operador. No hay razón para que el código no deba seguir esta convención.

Kevin Cline
fuente
0

Deje la expresión en una línea y, si se hace demasiado larga, divídala en expresiones más pequeñas:

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

se convierte en:

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

Si esto no es posible, entonces encuentro más legible romper antes que el operador, y hacer que el operador comience directamente debajo de la asignación anterior (ponerlo debajo de la variable me hace pensar y volver a centrarme, lo cual es molesto dado que el objetivo es hacer las cosas más fáciles de leer):

random = years * months_per_year 
         + month * days_per_month 
         + day * hours_per_day 
         + hour * minutes_per_hour 
         + minute * seconds_per_minute 
         + second
Joel
fuente
1
Esta respuesta no agrega nada nuevo a lo que ya se ha dicho.
Martijn Pieters