¿Deben aparecer llaves en su propia línea? [cerrado]

273

¿Deben las llaves estar en su propia línea o no? ¿Qué piensa usted al respecto?

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

o debería ser

if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}

o incluso

if (you.hasAnswer())
    you.postAnswer();
else
    you.doSomething();

¡Por favor se constructivo! Explique por qué, comparta experiencias, respalde con hechos y referencias.

Tom Wijsman
fuente
105
Encuentro que "== verdadero" es más molesto que la elección de la colocación de llaves.
Dan Dyer
11
@Dan: Creo que siempre explicar la expresión condicional ayuda mucho en la claridad.
Wizard79
44
La única razón por la que esto sería importante sería si su IDE / editor no es compatible con el reconocimiento de llaves.
leeand00
44
@ leeand00: algunos de nosotros todavía imprimimos código complejo / desconocido para estudiarlo / anotarlo. Sin embargo, una buena impresora bonita mitiga la mayoría de los problemas.
Shog9
2
triste la pregunta está cerrada. Después de un tiempo de uso de sintaxis basada en sangría, cambié a (quizás extraño) otra estructura de llaves. Como su primer pero cierre llave en la última línea de bloque. (después de la línea de código)
cnd

Respuestas:

88

Cuando era estudiante solía poner llaves en la misma línea, para que haya menos líneas y el código se imprima en menos páginas. Ver un solo carácter de paréntesis impreso como lo único en una línea es molesto. (medio ambiente, desperdicio de papel)

Pero al codificar aplicaciones grandes, permitir que algunas líneas con solo llaves sean asequibles, teniendo en cuenta la sensación de "agrupación" que da.

Sea cual sea el estilo que elija, sea coherente para que no se convierta en una sobrecarga para que su propio cerebro procese múltiples estilos en piezas de código relacionadas . En diferentes escenarios (como el anterior), diría que está bien usar diferentes estilos, es más fácil 'cambiar el contexto' a un alto nivel.

dbza
fuente
66
Por otro lado, el aparato ortopédico en la nueva línea es un ESTÁNDAR ANSI, K&R no lo es. Pero la belleza de los estándares es que hay tantos diferentes (ver también uncyclopedia.wikia.com/wiki/AAAAAAAAA ! En la enciclopedia).
Dilema el
"hay menos líneas" Tengo Terabytes of Space y muchos píxeles. ¿Por qué debería importarme usar más líneas?
12431234123412341234123
1
@ 12431234123412341234123: Creo que quiere decir porque algunas personas imprimen el código para revisarlo. Y cada nueva línea que no sea absolutamente necesaria se desperdicia en papel, o se desperdicia un km² de bosque a escala. Sin embargo, si no lo imprime (ciertamente no lo hago), entonces ANSI es mucho mejor que K&R. Además, cualquiera que tenga la intención de imprimir probablemente debería usar un formateador de código automatizado, por lo que esto debería ser una cuestión de herramientas, no de estilo de codificación.
Dilema del
247

Nunca debes hacer el 3er método.

Ojear los frenos puede ahorrarle algunas pulsaciones de teclas la primera vez, pero el siguiente programador que aparece agrega algo a su cláusula else sin darse cuenta de que al bloque le faltan frenillos va a tener mucho dolor.

Escribe tu código para otras personas.

rhettg
fuente
113
Desearía saber dónde se originó esa pequeña sabiduría. Porque escribir tu código para personas que no se molestarán en leerlo es tan inútil como puedas ...
Shog9
69
El segundo programador puede agregar sus propias llaves cuando agrega algo. No es estúpido, y en una convención de codificación que alienta a omitir llaves para cosas simples como esta, sabrá mirar.
Ken Bloom
25
Los frenos opcionales no son opcionales. Hay pocas decisiones de diseño peores que se tomaron en C y se trasladaron a sus descendientes. Que viva en un lenguaje tan reciente como C # me da rabia.
Adam Crossland
28
No importa cuán inteligente sea o cuán arraigado sea el estándar de codificación en torno a las curvas omitidas de una sola línea: si está buscando resolver un problema o error, es probable que se pierda que se omitieron las curvas. Y para un total de 2 segundos de trabajo, ¿es realmente tan malo ser explícito?
Jordan
11
Hay una ventaja en el estilo # 3 que todos se están perdiendo: obtienes más código en tu pantalla a la vez.
Loren Pechtel
203

Durante mucho tiempo sostuve que tenían el mismo valor, o tan cerca de igual que la posible ganancia al tomar la decisión correcta estaba muy, muy por debajo del costo de discutir sobre eso.

Sin embargo, ser consistente es importante . Así que dije que volteemos una moneda y empecemos a escribir el código.

He visto a programadores resistirse a cambios como este antes. ¡Superalo! He cambiado muchas veces en mi carrera. Incluso uso diferentes estilos en mi C # que en mi PowerShell.

Hace unos años, estaba trabajando en un equipo (~ 20 desarrolladores) que decidió solicitar información y luego tomar una decisión y luego aplicarla en toda la base de código. Tendríamos 1 semana para decidir.

Muchos gemidos y ojos rodantes. Un montón de "Me gusta mi camino, porque es mejor", pero sin sustancia.

Mientras estábamos estudiando los puntos más finos de la pregunta, alguien preguntó cómo lidiar con este problema en un estilo de refuerzo en la misma línea:

void MyFunction(
    int parameterOne,
    int parameterTwo) {
    int localOne,
    int localTwo
}

Tenga en cuenta que no es inmediatamente obvio dónde termina la lista de parámetros y comienza el cuerpo. Comparar con:

void MyFunction(
    int parameterOne,
    int parameterTwo) 
{
    int localOne,
    int localTwo
}

Leímos un poco sobre cómo la gente de todo el mundo había tratado este problema, y ​​encontramos el patrón de agregar una línea en blanco después del paréntesis abierto:

void MyFunction(
    int parameterOne,
    int parameterTwo) {

    int localOne,
    int localTwo
}

Si vas a hacer un descanso visual, también puedes hacerlo con un aparato ortopédico. Entonces tus pausas visuales también se vuelven consistentes.

Editar : Dos alternativas a la solución de 'línea en blanco adicional' cuando se usa K&R:

1 / Sangrar los argumentos de la función de manera diferente del cuerpo de la función

2 / Coloque el primer argumento en la misma línea que el nombre de la función y alinee más argumentos en nuevas líneas con ese primer argumento

Ejemplos:

1 /

void MyFunction(
        int parameterOne,
        int parameterTwo) {
    int localOne,
    int localTwo
}

2 /

void MyFunction(int parameterOne,
                int parameterTwo) {
    int localOne,
    int localTwo
}

/Editar

Todavía sostengo que la consistencia es más importante que otras consideraciones, pero si no tenemos un precedente establecido , entonces prepararse en la siguiente línea es el camino a seguir.

Jay Bazuzi
fuente
33
FYI, puedo parecer una persona razonable, pero en realidad soy un loco. Para bloques simples de una sola línea, no usaré llaves ni líneas nuevas, haciendo que 'if (foo) bar ()' sea una sola línea. Me esfuerzo por hacer que mi código sea lo suficientemente simple como para que no sea un problema.
Jay Bazuzi
38
Vine aquí para publicar exactamente esto. Toneladas de personas que mantienen la llave de apertura en la misma línea la siguen con una línea en blanco (especialmente al comienzo de las clases y métodos) porque de lo contrario, es difícil separar el encabezado de clase / método del cuerpo. Bueno, si va a utilizar una línea extra de todos modos, también puede colocar el aparato ortopédico allí y obtener el beneficio adicional de que la sangría sea más fácil de ver.
Yevgeniy Brikman
27
No he visto la línea en blanco: estoy más familiarizado con la doble sangría de los parámetros para MyFunction () cuando se desvían a otra línea.
Armand
34
Desglosar los parámetros en varias líneas como esa es una locura.
Fosco
10
El argumento del "parámetro de función" es una pista falsa. Obviamente, los argumentos deben ser de doble intención. No hay problema alguno para distinguirlo del siguiente código.
David Ongaro
99

Las reglas cardinales son:

  1. Siga el estándar de codificación existente del proyecto.
  2. Si no hay un estándar de codificación y está editando una base de código existente propiedad de otra persona, sea coherente con el estilo del código existente, sin importar cuánto le guste / no le guste.
  3. Si está trabajando en un proyecto de campo verde, discuta con otros miembros del equipo y llegue a un consenso sobre un estándar de codificación formal o informal.
  4. Si está trabajando en un proyecto de campo verde como único desarrollador, decídase y sea implacablemente coherente.

Incluso si no tiene restricciones externas, es (IMO) el mejor buscar un estándar de codificación existente (ampliamente utilizado) o una directriz de estilo, y tratar de seguirlo. Si desarrolla su propio estilo, existe una buena posibilidad de que lo lamente en unos años.

Finalmente, un estilo que se implementa / implementa usando los verificadores de estilo y los formateadores de código existentes es mejor que uno que deba "aplicarse" manualmente.

Stephen C
fuente
10
Esta respuesta merece más votos.
AShelly
1
la consistencia es la clave
MediaVince
70

El beneficio del primer método es que es más verticalmente compacto, por lo que puede colocar más código en su pantalla, y es por eso que lo prefiero. El único argumento que escuché a favor del segundo método es que facilita emparejar corchetes de apertura y cierre, pero la mayoría de los IDE tienen un atajo de teclado para eso, y en realidad es una declaración falsa, en lugar de emparejar un corchete de apertura con un cierre corchete puede emparejar un corchete de cierre con la expresión "inicio del bloque" (if, else, for, while) en el mismo nivel de sangría, por lo que es igual de fácil determinar dónde está el inicio del bloque.

No veo ninguna razón para desperdiciar una línea completa solo para un corchete cuando la construcción anterior para / while / if ya indica visualmente el inicio de un bloque.

Dicho esto, creo que el corchete de cierre debe estar en su propia línea porque necesitamos algo para indicar el final de un bloque y su estructura de sangría de manera visible.

revs EpsilonVector
fuente
12
No ... digo por qué reducir la cantidad de código que puede caber en su pantalla haciendo algo que no agregue claridad al código.
EpsilonVector
66
Cuando comencé a codificar, me gustó cada llave en su propia línea, ahora prefiero el primer método
NimChimpsky, el
57
Existe un gran cuerpo de investigación, que se remonta a la temprana edad de Steam (Weinberg, "Psicología de la programación de computadoras"), que muestra que la comprensión del programador disminuye DRAMÁTICAMENTE cuando la cantidad de código que debe verse es más de lo que puede ser visto al mismo tiempo (es decir, una pantalla, una página de impresora). Este fenómeno argumenta enérgicamente para ver el espacio vertical como un recurso valioso, que no debe desperdiciarse de forma gratuita, por lo que se prefiere el primer método.
John R. Strohm
10
LOL @ "desperdiciando una línea COMPLETA". ¡DIOS MIO! ¡¡Eso no!! = P
Nick Spreitzer
66
@Julio En la universidad, prefería el método 1, y no podía soportar leer el método 2. Después de ir a trabajar a una empresa que usa C #, donde el estándar es el método 2, me ha gustado mucho. Ahora puedo leer o usar cualquiera; ninguno me molesta. Las personas que tienen una reacción muy negativa a uno u otro generalmente reaccionan de forma exagerada a algo con lo que no están familiarizados.
KChaloux
46

yo prefiero

if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}

terminado

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

porque la línea you.postAnswer();es mucho más fácil de leer y encontrar a primera vista. En la segunda forma, se mezcla con la línea que está arriba ( you.hasAnswer()), lo que hace que mis ojos tengan que enfocarse más para leerlo.

JD Isaacks
fuente
77
Esto es cierto hasta que su programa exceda la altura de su pantalla. ;)
weberc2
13
@ weberc2 Creo que cuando su programa excede la altura de la pantalla, dos líneas menos no cambiarán mucho.
Mageek
13
Hace 10 años, habría acordado sobre el espacio de la pantalla. Hoy, uso una pantalla de 1920 * 1200. Encaja MUCHO código, más de lo que mi cerebro puede procesar a la vez. El primer método me permite retroceder y ver los diferentes alcances de apertura / cierre sin tener que leerlo.
LightStriker
3
Nunca podría entender por qué prefería este método, pero es exactamente para esto.
Declan McKenna
2
@Mageek Esto es tardío, pero no son 2 líneas, son 2 líneas para cada alcance. Eso es O (N), no O (1). Realmente no me siento tan fuerte al respecto; Es más importante que elija un estilo que haga legibles las largas listas de parámetros.
weberc2
38

Prefiero el primer método Los frenos no valen totalmente la línea separada.

La cuestión es que los frenos no son importantes. Son solo basura sintáctica , que es absolutamente innecesaria para comprender para qué sirve el código, su propósito y la forma en que se implementa. Son solo un homenaje a los antiguos lenguajes tipo C donde la agrupación visual de operadores era imposible debido al bajo espacio disponible en la pantalla.

Hay lenguajes (Python, Haskell, Ruby) que están bien sin llaves. Esto solo confirma que los frenos son basura, y no debería merecer una línea para ellos siempre que sea posible:

if (you.hasAnswer()){
    you.postAnswer();
}else{
    you.doSomething();
}
P Shved
fuente
77
No sé acerca de Haskell o Ruby, pero Python es sensible al espacio en blanco, por lo que no requiere llaves u otros delimitadores para denotar bloques. Los frenos no son solo ruido sintáctico; Sirven un propósito real.
Robert Harvey
14
@ Robert, en C que tiene que hacer tanto espacios en blanco y los apoyos. En Python debes hacer solo espacios en blanco. ¿Cual es mejor?
P Shved
55
@Pavel, en C 'no tienes que hacer espacios en blanco.
Ken Bloom
77
Los programas de @KenBloom C sin espacios en blanco son imposibles de leer. Entonces tienes que hacerlos de todos modos.
P Shved
66
Independientemente de si los frenos son una buena idea o no, la mera existencia de idiomas que no los usan no parece un argumento a favor o en contra de ellos. Solo sugiere que es posible tener un idioma sin ellos, no que sea un diseño de lenguaje bueno o malo.
Jason
37

Usa Python y esquiva el argumento por completo.

Mark Ransom
fuente
17
+1SyntaxError: not a chance
Seth
66
Esto simplemente no es una opción para la gran mayoría de los proyectos. Además, la sangría para la agrupación tiene muchos problemas.
Bryan Oakley
@Bryan, me doy cuenta de que esto no es muy práctico. Solo pensé que era un punto de vista que necesitaba estar ahí afuera, más fuerte que solo un comentario. Y nunca me he encontrado con los problemas causados ​​por la sangría que implicas, probablemente porque no mezclo pestañas y espacios.
Mark Ransom
Use Ir y esquive el argumento por completo (¡además de tipeo estático, velocidad y un compilador!) :)
weberc2
44
Luego presione la barra espaciadora demasiadas veces y vea cómo el compilador / intérprete se ríe de usted. Eso no sucederá en la mayoría de los idiomas ortopédicos.
Pharap
28

La posición de las llaves debe ser

metadatos

configurable en el IDE por el programador. De esa manera, esas llaves molestas en todo el código, independientemente del autor, se ven iguales.

Jonathan
fuente
77
Totalmente de acuerdo. Es presentación y no datos.
Petruza el
El problema es que si dejas que todos establezcan las suyas, las cosas se complican muy rápidamente a medida que se realizan los compromisos.
Andy
1
@Andy: Ese es exactamente el punto, el IDE cambiará su aspecto, ¡pero solo en el IDE! La fuente real no será tocada. Para el control de versiones, puede agregar ganchos que traducen cualquiera que sea la configuración de las llaves en una situación común, para que todos revisen el código de la misma manera.
klaar
@klaar Cada IDE moderno que he usado cambiará las pestañas a espacios y moverá las llaves a su propia línea o al final de la línea de "apertura"; No estoy seguro de por qué crees que no se toca la fuente en estos casos, y esa es la razón de mi comentario. Por lo general, los IDE lo cambian según la configuración de los desarrolladores, lo que significa que durante una confirmación veré muchos cambios que son solo ruido a medida que las llaves se movieron a su propia línea, ocultando así el cambio REAL que alguien hizo.
Andy
@Andy: ¿No existe la posibilidad de usar ganchos que conviertan esas discrepancias con respecto a los espacios en blanco y los corchetes en un compromiso estándar uniforme, para evitar el problema de ruido que describiste? De cualquier manera, un sistema de versiones adecuado debería trascender cosas insignificantes como espacios en blanco u otras cosas sin sentido.
klaar
19

Depende.

Si estoy codificando en Javascript o jQuery, utilizo el primer formulario:

jQuery(function($) { 
    if ($ instanceOf jQuery) { 
        alert("$ is the jQuery object!"); 
    } 
}); 

Pero si estoy codificando en C #, utilizo la segunda forma, porque esa es la forma canónica de hacerlo en C #.

public int CalculateAge(DateTime birthDate, DateTime now) 
{ 
    int age = now.Year - birthDate.Year; 
    if (now.Month < birthDate.Month 
        || (now.Month == birthDate.Month && now.Day < birthDate.Day)) 
        age--; 
    return age; 
} 

Tenga en cuenta que su ejemplo puede ser escrito

if (you.hasAnswer())
    you.postAnswer();
else
    you.doSomething();

Cía#.

Robert Harvey
fuente
1
Se puede escribir en muchos idiomas como ese, porque una declaración de bloque es una declaración. Agregando! :-)
Tamara Wijsman
2
De acuerdo con las "Directrices de diseño del marco", la "forma canónica" es colocar la llave de apertura en la misma línea (es decir, la primera forma). Solo
digo
3
@Uwe: Quizás. Pero Microsoft adoptó el enfoque de "llaves alineadas" para todos sus ejemplos de MSDN C #, y está integrado en Visual Studio, así que ...
Robert Harvey
@Uwe: Ese es el libro de Cwalina y tiene un nombre terrible, ya que es mucho más que eso. El FDG en MSDN no tiene nada que decir al respecto. También me pregunto, ¿por qué las Directrices de diseño de marcos dicen algo sobre la práctica de codificación de C # ?
R. Martinho Fernandes
3
De hecho, debería colocar llaves en la misma línea en Javascript. Puede causar errores si las llaves están en su propia línea. Por ejemplo, vea encosia.com/…
Joseph Hansen
18

Prefiero el primero porque es más difícil para mí ver el error en este ejemplo.

if (value > maximum);
{
    dosomething();
}

de lo que es en este ejemplo

if (value > maximum); {
    dosomething();
}

El ; {tiene un aspecto más mal a mí que una línea que termina con ;lo que estoy más probabilidades de notarlo.

bmb
fuente
11
Haces un buen argumento, pero personalmente, esto solo me ha pasado una vez en mis 5 años de programación. No podía entender por qué no se estaba ejecutando, lo publiqué en SO y alguien rápidamente me señaló el punto y coma. Sin embargo, cada vez que se condensa usar esa línea 1 menos, me resulta más difícil de leer.
JD Isaacks el
66
El "; {" parece una especie de cara gruñona que parpadea o tal vez una persona con bigote.
glenatron
+1 Gran ejemplo en respuesta: error muy sutil, fácil de pasar por alto. El pensamiento también provoca en el diseño que muestra esto.
therobyouknow
10
Por supuesto, cualquier IDE decente marcará la declaración de control vacía y cualquier compilador decente emitirá una advertencia.
Dunk
@Dunk El único defecto en su argumento (con el que estoy totalmente de acuerdo) es que tanta gente está utilizando lenguajes interpretados en estos días (JavaScript, PHP, etc.) que muchos "programadores" no conocerían un compilador de un doble latté.
Craig
15

Prefiero una ligera variante de 1)

if (you.hasAnswer()) {
    you.postAnswer();
} // note the break here
else {
    you.doSomething();
}

¿Por qué?

  • Creo que siempre poner llaves en su propia línea disminuye la legibilidad. Solo puedo colocar una cierta cantidad de código fuente en mi pantalla. El estilo de soporte 2) crea algoritmos de levantamiento con muchos bucles anidados y condicionales dolorosamente largos.

  • Sin embargo, quiero elsecomenzar en una nueva línea porque ify estar elsejuntos, visualmente. Si hay un soporte delante de elseél, es mucho más difícil detectar qué pertenece a qué.

  • 3) se descalifica a sí mismo. Todos sabemos qué cosas malas pueden pasar si omites los corchetes y te olvidas de ello.

Alexander Gessler
fuente
1
He visto este alrededor de donde trabajo. Es interesante.
Almo
1
También me gusta más este estilo, ya que me permite poner comentarios encima de la elselínea cuando sea necesario, y / o poner una línea en blanco entre el bloque if y el bloque else para que las cosas se vean menos abarrotadas. El estilo de soporte # 2 no hace más que distanciar las acciones de las condiciones. Dicho esto, mi favorito es definitivamente el estilo sin soporte de Python :)
sayap
44
Si es importante maximizar el número de líneas de código en la pantalla, simplemente elimine las nuevas líneas por completo. Podrás obtener muchas líneas en una pantalla. Prefiero no tener nada que me detenga y piense mientras leo, es decir. Mi definición de más legible. Con los frenos, mi mente los ignora. Sin los frenos, mi mente tiene que pausar y alinear los bloques de control. No es una pausa larga, pero una pausa, no obstante.
Dunk
1
Sí, si y de lo contrario pertenecen juntos, PERO también {y} y como} está en una línea separada, {también debería estar en una línea separada. "Solo puedo colocar una cierta cantidad de código fuente en mi pantalla" Y eso es exactamente por qué decir que el 3) sería "descalificar a sí mismo" no es una opción en absoluto. Después de una década de trabajar con 3), nunca he olvidado agregar corchetes al agregar una nueva línea de código, ni conozco a nadie que haya tenido alguna vez. Si tengo que ajustar el código a las personas que no pueden leer correctamente, ¿dónde termina? ¿Dejar de usar ciertas características del lenguaje porque algunos de los lectores de códigos pueden no entenderlas?
Kaiserludi

10

Leí en alguna parte que los autores de algún libro querían que su código tuviera el siguiente formato:

if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}

Pero las limitaciones de espacio de su editor significaron que tenían que usar esto:

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

Ahora no sé si eso es cierto (ya que no puedo encontrarlo más), pero este último estilo es muy frecuente en los libros.

A nivel personal, prefiero los corchetes en una línea separada como:

a) indican un nuevo alcance
b) es más fácil de detectar cuando tiene una falta de coincidencia (aunque esto es un problema menor en un IDE que resalta los errores para usted).


... La segunda opción también facilita sus dos puntos (solo con la sangría que sirve para el combo de corsé / sangría). :)
weberc2

10

Ah, el estilo de un verdadero aparato ortopédico .

Tiene todo lo necesario para un Camino Santo, incluso un profeta (Richard "mi camino o la carretera" Stallman).

El tipo estaba tan equivocado acerca de tantas cosas, pero GNU es perfecto cuando se trata de aparatos ortopédicos.


[Actualización] He visto la luz, y ahora adoro a Allman


99
No veo el punto del estilo GNU, aparte de que modela el código lisp. Parece mucho trabajo por poco beneficio.
Robert Harvey

No conozco a nadie que use el estilo GNU. 1TBS hasta el final.
Jé Queue

No puedes hacer nada peor que dos niveles de sangría por bloque, excepto por el estilo lisp, por supuesto, eso es evidente.
ergosys

44
+1 para el enlace en estilos de llaves. Muestra que sea cual sea tu estilo, muchas personas geniales no están de acuerdo contigo.
Florian F

@RobertHarvey No hay trabajo adicional, si es así, no utiliza la herramienta adecuada para escribir código o no lo configura correctamente. El beneficio es un código mucho más legible, ves cada error en el soporte muy rápido y puedes leer fácilmente solo el código mientras ignoras los subbloques.
12431234123412341234123

9

Segundo ejemplo, soy muy grande en cuanto a legibilidad. No puedo soportar mirar si los bloques de otra manera = (


1
La investigación indica que es más fácil leer el código compacto una vez que la base del código excede la altura de la pantalla.
weberc2

55
@ weberc2, ¿podría proporcionar DOI a esos trabajos de investigación?
Grzegorz Adam Kowalski

9

Respuesta simple: ¿qué es más fácil de depurar?

// Case 1:
void dummyFunction() {
  for (i = 0; i != 10; ++i) {
    if (i <= 10)
      std::cout << "i is: " << i << "\n";
      std::cout << 10 - i << " steps remaining\n";

      // Some hard work here
      // which is really hard
      // and does take some screen estate
    }
    else
      std::cout << "We'll never get there";
  }
} // COMPILER ERROR HERE


// Case 2:
void dummyFunction()
{
  for (i = 0; i != 10; ++i)

    if (i <= 10)
    {
      std::cout << "i is: " << i << "\n";
      std::cout << 10 - i << " steps remaining\n";

      // Some hard work here
      // which is really hard
      // and does take some screen estate
    }
    else
      std::cout << "We'll never get there\n";
  }
} // COMPILER ERROR HERE

¿En qué caso diagnosticó el problema primero?

No me interesan mucho las preferencias personales (hay muchos otros estilos, incluyendo whitesmith y otros) y no me importan mucho ... siempre que no obstaculice mi capacidad de leer el código y depurarlo .

En cuanto al argumento del "espacio de desperdicio", no lo compro: tiendo a agregar líneas en blanco entre los grupos lógicos de todos modos para aclarar el programa ...


1
Ambos son tan fáciles de depurar, principalmente porque es un pequeño bloque de código. La sangría es consistente, lo que facilita la visualización de los bloques de código reales.
Htbaa

@Htbaa: de hecho :) Entonces, ¿por qué molestarse?
Matthieu M.

@MatthieuM. El primer bloque tiene más sentido para mí, porque las nuevas líneas (en el segundo bloque) entre la firma de la función, la declaración for y la declaración if me hacen creer que no están relacionadas, pero claramente no lo están. Las líneas en blanco son para separar bits de código no relacionados; El código que está cerca de otras líneas de código significa que, de hecho, están relacionadas. Todo esto es 'imo', por supuesto, pero me preguntaba cuál era su punto. EDITAR: también cualquier IDE adecuado notará que faltan llaves y le dará una pequeña cantidad de errores al interpretar su código.
klaar

7

No es que nadie lo note, pero esta es la razón por la cual los frenos pertenecen a la misma línea que el condicional (excepto para condicionales muy largos, pero ese es un caso límite):

En C, esta es una construcción válida:

mientras (verdadero);
{
    char c;
    getchar (); // Espera entrada
}

¡Rápido! ¿Qué hace este código? Si respondiste "bucle infinito pidiendo entrada", ¡estás equivocado! Ni siquiera llega a la entrada. Queda atrapado en while(true). Observe ese punto y coma al final. Este patrón es en realidad más común de lo que parece que debería ser; C requiere que declare sus variables al comienzo de un bloque, por lo que se inició una nueva.

Una línea de código es un pensamiento. Las llaves son parte del pensamiento que contiene el condicional o el bucle. Por lo tanto, pertenecen a la misma línea.

Christian Mann
Este es, con mucho, el mejor argumento para el estilo K&R que he visto, el resto es ridículo con los sistemas IDE de hoy en día con soporte de plegado de código. Esto solo se aplica a los lenguajes de estilo C que admiten ;extremos de bloque. Esta es también la razón por la que desprecio este sistema de finalización de bloque que, en mi humilde opinión, está desactualizado y el lenguaje Go lo demuestra. He visto este problema muchas veces, aunque no en este escenario. Por lo general, ocurre cuando tienen la intención de agregar algo a la declaración y se olvidan de hacerlo.
Jeremy
para usarse así, postAnswer()y doSomething()debería devolver el valor para el operador ternario, que a menudo no es el caso: muy bien pueden devolver nulo (sin valor). y también (al menos en c #) el resultado de ?:debe asignarse a alguna variable
ASh
44
Como muestra su ejemplo, la sangría es tan importante como las llaves para el código legible. De hecho, ¡algunos idiomas hacen que la sangría sea la única forma de anidar declaraciones!
1
Ok, honestamente encuentro que tu ejemplo inconsistente es difícil de leer. No REALMENTE difícil, pero más difícil que si fuera consistente.
Almo
Estoy de acuerdo con Almo. No es un caso de "¿es realmente difícil". Es un caso de "definitivamente es más difícil", incluso si no es difícil. Entonces, ¿por qué hacer las cosas más difíciles? En los ejemplos de "juguetes" que la gente da, por supuesto, hay poca diferencia. En mi experiencia, cuando heredé código desagradable de otra persona y usaron el método 1, con frecuencia es necesario seguir adelante y convertirlo en el método 2 solo para poder seguir la lógica. Por el hecho de que con frecuencia se hace necesario; Responde automáticamente a la pregunta de qué método es mejor y más fácil de entender.
Dunk
@Dunk: No puedo entender el código que mejoraría notablemente intercambiando detalles tan irrelevantes.
jkerian
@ jkerian-Aparentemente no has heredado mucho código de otros que han dejado el proyecto o la compañía. No puedo imaginar no encontrarme con esa situación por alguien con algunos años de experiencia. Pero, de nuevo, la situación laboral de cada persona es diferente. Además, si tiene que hacer revisiones de código "formales", el formateo marca una gran diferencia. Poder leer el código naturalmente es muy importante. Claro que puedo hacer una pausa y pensar en unir llaves, pero eso ralentiza el proceso. Una forma no requiere pausas, las otras sí. Es por eso que no veo por qué se podría recomendar otra opción.
Dunk
Los veteranos como yo usan tres teclas para seleccionar el bloque sin importar dónde estén las malditas llaves.
ergosys
8
Malo, malo, quiero decir terrible, terrible ejemplo. ¡El problema no son las llaves! ¡Es la sangría loca!
R. Martinho Fernandes
@Martinho Fernandes pensé que la colocación de llaves y sangrado van de la mano ...
AndrejaKo
2
no necesariamente ... haga una sangría adecuada en lo anterior y luego cambie aleatoriamente los estilos de llaves, encontrará que es comprensible.
jkerian
De hecho, pensar en esto motivó mi propia respuesta a esta pregunta.
jkerian
"El 95% de los errores en el programa que realizó provienen de llaves no coincidentes", solo en idiomas interpretados, no compilados.
Mawg
3
El estilo C siempre me molestó. ¡Se consistente!
Christian Mann
55
+1, -1. ¿Por qué NO sangraría con pestañas ya que cualquier editor puede ajustar la longitud de la pestaña a su longitud arbitraria? De lo contrario, llevas a muchos de nosotros que nos gustan las sangrías verdaderas a las 8 para maldecir tu código.
Jé Queue
99
... al igual que la mayoría de los programadores que se ahogarían con esto.
Jé Queue
44
Eso parece horrible. Piense en el esfuerzo adicional que debe realizar si desea insertar una línea en la parte superior o eliminar la línea superior. No puede simplemente eliminar la línea y seguir adelante, debe recordar volver a insertar la llave.
Bryan Oakley
jajaja esto es genial! :) mejor que el primer estilo!
nawfal
Al parecer, incluso tiene un nombre. El Horstman Syyle se menciona en wikipedia . He trabajado con una base de código como esta, realmente no es malo usarla.
AShelly
2
Peor aún sería si alguien viniera y lo hiciera: if (you.hasAnswer ()) you.postAnswer (); de lo contrario you.doSomething (); you.doSomethingElse (); - es una receta para errores sutiles que el ojo puede pasar fácilmente y el compilador tampoco ayudará
FinnNk
@FinnNk: ¡Exactamente!
Chankey Pathak
2
Si alguien quiere agregar otra declaración, puede poner los corchetes ellos mismos. Cualquier programador que valga la pena realmente debería ser capaz de resolverlo.
Robert Harvey
Quería decir que su tercer método está mal.
Chankey Pathak
3
@Robert Harvey, he visto a codificadores muy experimentados que no agregan las llaves al modificar el código existente. Creo que el problema es que la sangría es una pista de significado mucho más fuerte que las llaves (especialmente porque hay varios estilos de llaves), por lo que es bastante fácil pasar por alto la llave faltante si la sangría se parece a lo que esperas.
AShelly
5

Me gusta el primer método Parece IMO más ordenado, y es más compacto, lo que me gusta.

EDITAR: Ah, un tercero. Me gusta ese mejor cuando sea posible, ya que es aún más pequeño / ordenado.

revs Ullallulloo
fuente
5

Podrías escribirlo:

you.hasAnswer() ? you.postAnswer() : you.doSomething();

Para responder la pregunta; Solía ​​preferir llaves en su propia línea, pero, para evitar tener que pensar en los errores de la inserción automática de punto y coma en los navegadores, comencé a usar el estilo egipcio para javascript. Y cuando codifiqué java en eclipse, no tenía interés en pelear (o configurar) el estilo de llave predeterminado, así que también fui con egipcio en ese caso. Ahora estoy bien con ambos.

FeatureCreep
fuente
para usarse así, postAnswer()y doSomething()debería devolver el valor para el operador ternario, que a menudo no es el caso: muy bien pueden devolver nulo (sin valor). y también (al menos en c #) el resultado de ?:debe asignarse a alguna variable
ASh
4

Casi todas las respuestas aquí están diciendo alguna variación en "Hagas lo que hagas, quédate con uno o dos".

Así que lo pensé por un momento y tuve que admitir que simplemente no lo veo tan importante. ¿Alguien puede decirme honestamente que lo siguiente es difícil de seguir?

int foo(int a, Bar b) {
    int c = 0;
    while(a != c)
    {
        if(b.value[a] == c) {
            c = CONST_A;
        }
        c++;
    }
    return c;
}

No estoy seguro de nadie más ... pero tengo absolutamente cero problemas para cambiar mentalmente de un estilo a otro. Me tomó unos momentos descubrir qué hizo el código, pero ese es el resultado de que escribí aleatoriamente una sintaxis tipo C. :)

En mi opinión no tan humilde, abrir llaves es casi completamente irrelevante para la legibilidad del código. Hay algunos casos de esquina enumerados anteriormente donde un estilo u otro hace la diferencia, pero en su mayor parte, el uso prudente de las líneas en blanco lo limpia.

FWIW, nuestros estilos de codificación en el trabajo utilizan una forma 1 un poco más estructurada y una forma modificada 3. (C ++)

            // blank line is required here
if (x) {
            //This blank line is required
   y = z;
}
            // blank line is required here too, unless this line is only another '}'

if (x) y = z; //allowed

if (x)
    y = z;  // forbidden

Tengo curiosidad si aquellos que prefieren la forma 2 encontrarían mejor esta versión de la forma 1, solo porque la línea en blanco proporciona una separación visual más fuerte.

jkerian
fuente
44
Como muestra su ejemplo, la sangría es tan importante como las llaves para el código legible. De hecho, ¡algunos idiomas hacen que la sangría sea la única forma de anidar declaraciones!
1
Ok, honestamente encuentro que tu ejemplo inconsistente es difícil de leer. No REALMENTE difícil, pero más difícil que si fuera consistente.
Almo
Estoy de acuerdo con Almo. No es un caso de "¿es realmente difícil". Es un caso de "definitivamente es más difícil", incluso si no es difícil. Entonces, ¿por qué hacer las cosas más difíciles? En los ejemplos de "juguetes" que la gente da, por supuesto, hay poca diferencia. En mi experiencia, cuando heredé código desagradable de otra persona y usaron el método 1, con frecuencia es necesario seguir adelante y convertirlo en el método 2 solo para poder seguir la lógica. Por el hecho de que con frecuencia se hace necesario; Responde automáticamente a la pregunta de qué método es mejor y más fácil de entender.
Dunk
@Dunk: No puedo entender el código que mejoraría notablemente intercambiando detalles tan irrelevantes.
jkerian
@ jkerian-Aparentemente no has heredado mucho código de otros que han dejado el proyecto o la compañía. No puedo imaginar no encontrarme con esa situación por alguien con algunos años de experiencia. Pero, de nuevo, la situación laboral de cada persona es diferente. Además, si tiene que hacer revisiones de código "formales", el formateo marca una gran diferencia. Poder leer el código naturalmente es muy importante. Claro que puedo hacer una pausa y pensar en unir llaves, pero eso ralentiza el proceso. Una forma no requiere pausas, las otras sí. Es por eso que no veo por qué se podría recomendar otra opción.
Dunk
4

Me sorprende que esto no se haya planteado todavía. Prefiero el segundo enfoque porque te permite seleccionar el bloque más fácilmente.

Cuando las llaves comienzan y terminan en la misma columna y en su propia línea, puede seleccionar desde el margen o con el cursor en la columna 0. Esto generalmente equivale a un área más generosa con la selección del mouse o menos pulsaciones de teclas con la selección del teclado.

Originalmente trabajé con llaves en la misma línea que el condicional, pero cuando cambié, encontré que aceleraba la velocidad a la que trabajaba. No es de día ni de noche, por supuesto, pero es algo que lo retrasará un poco al trabajar con aparatos ortopédicos junto a sus condicionales.

Tim O'Neil
fuente
Los veteranos como yo usan tres teclas para seleccionar el bloque sin importar dónde estén las malditas llaves.
ergosys
2

Personalmente me gusta la segunda forma.

Sin embargo, la forma en que voy a demostrar es, en mi opinión, ¡la mejor porque da como resultado una mayor seguridad laboral! Un compañero de mi universidad me pidió ayuda con su tarea y así es como se veía su código. Todo el programa parecía un solo bloque. Lo interesante es que el 95% de los errores en el programa que hizo provienen de llaves no coincidentes. El otro 5% fue obvio una vez que se combinaron las llaves.

while(1){
i=0;
printf("Enter coded text:\n");
while((s=getchar())!='\n'){
         if(i%1==0){
            start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!");
exit(1);}
input=start;}
      input[i++]=s;}
start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!!!");
exit(1);}
input=start;
input[i]='\0';
                puts(input);
AndrejaKo
fuente
8
Malo, malo, quiero decir terrible, terrible ejemplo. ¡El problema no son las llaves! ¡Es la sangría loca!
R. Martinho Fernandes
@Martinho Fernandes pensé que la colocación de llaves y sangrado van de la mano ...
AndrejaKo
2
no necesariamente ... haga una sangría adecuada en lo anterior y luego cambie aleatoriamente los estilos de llaves, encontrará que es comprensible.
jkerian
De hecho, pensar en esto motivó mi propia respuesta a esta pregunta.
jkerian
"El 95% de los errores en el programa que realizó provienen de llaves no coincidentes", solo en idiomas interpretados, no compilados.
Mawg
2

Mi preferencia personal es el primer método, probablemente porque esa es la forma en que aprendí PHP por primera vez.

Para ifdeclaraciones de una sola línea , usaré

if (you.hasAnswer()) you.postAnswer();

Si no lo es, you.postAnswer();pero algo mucho más largo, como you.postAnswer(this.AnswerId, this.AnswerText, this.AnswerType);probablemente volveré al primer tipo:

if (you.hasAnswer) {
    you.postAnswer(this.AnswerId, this.AnswerText, this.AnswerType);
}

Nunca usaré un salto de línea, y nunca usaré este método si también hay una elsedeclaración.

if (you.hasAnswer()) you.postAnswer();
else you.doSomething()

Es una posibilidad teórica, pero nunca la usaría. Esto tendría que ser convertido en

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}
Trigonometría
fuente
2

No deberian; primer método para mi

Cuando miro el segundo, debido a las líneas no utilizadas (aquellas que solo tienen llaves, aparte de la última llave de cierre), parece que rompe la continuidad del código. No puedo leerlo tan rápido porque necesito prestar especial atención a las líneas vacías, que generalmente significan una separación en el propósito del código o algo así, pero en ningún caso "esta línea pertenece a una llave" (que solo repite el significado de sangría).

De todos modos, al igual que cuando escribe texto ... agregar una sangría al comienzo de un párrafo es superfluo si hay una línea en blanco antes (doble signo de cambio de párrafo), no hay necesidad de desperdiciar líneas para llaves cuando estamos sangría adecuada.

Además, como ya se dijo, permite colocar más código en la pantalla, que de lo contrario es un poco contraproducente.

Joanis
fuente
2

Depende de la plataforma / idioma / convenciones

En Java:

void someMethod() { 
     if (you.hasAnswer()) {
         you.postAnswer();
     } else {
       you.doSomething();
     }
}

Cía#

void someMethod() 
{ 
     if (you.hasAnswer()) 
     {
         you.postAnswer();
     } 
     else 
     {
       you.doSomething();
     }
}

Cía:

void someMethod() 
{ 
     if (you_hasAnswer()) {
         you.postAnswer();
     } else {
       you_doSomething();
     }
}

Odio cuando los chicos de Java usan su estilo en código C # y viceversa.

revs OscarRyz
fuente
3
El estilo C siempre me molestó. ¡Se consistente!
Christian Mann
1

Todo lo que puedo decir es que si eres fanático del método # 3, serás perseguido por cada formateador de código IDE en la tierra.

Phil Cohen
fuente
1

Utilizo el primer método simplemente porque es más compacto y permite más código en la pantalla. Yo mismo nunca he tenido problemas para emparejar llaves (siempre las escribo, junto conif declaración antes de agregar la condición, y la mayoría de los entornos le permiten saltar a la llave correspondiente).

Si usted qué necesita para emparejar los apoyos visuales, entonces yo preferiría el segundo método. Sin embargo, eso permite menos código a la vez, lo que requiere que se desplace más. Y eso, al menos para mí, tiene un mayor impacto en la lectura del código que tener llaves cuidadosamente alineadas. Odio el desplazamiento. Por otra parte, si necesita desplazarse por una sola ifdeclaración, lo más probable es que sea demasiado grande y necesita una refactorización.

Pero; Lo más importante de todo es la consistencia. Use uno u otro, ¡nunca ambos!

gablin
fuente
0

Cuando estaba aprendiendo programación a los 12, puse los corchetes en la siguiente línea porque los tutoriales de codificación de Microsoft son así. También sangré con TABS de 4 espacios esa vez.

Después de unos años, aprendí Java y JavaScript, y vi más código de llaves en la misma línea, así que cambié. También comencé a sangrar con espacios de 2 espacios.

Ming-Tang
fuente
55
+1, -1. ¿Por qué NO sangraría con pestañas ya que cualquier editor puede ajustar la longitud de la pestaña a su longitud arbitraria? De lo contrario, llevas a muchos de nosotros que nos gustan las sangrías verdaderas a las 8 para maldecir tu código.
Jé Queue
0

Hay una cuarta opción que mantiene los tirantes alineados, pero no desperdicia espacio:

if (you.hasAnswer())
{    you.postAnswer();
     i.readAnswer();
}
else
{   you.doSomething();
}

El único problema es que la mayoría de los autoformadores de IDE se ahogan con esto.

AShelly
fuente
99
... al igual que la mayoría de los programadores que se ahogarían con esto.
Jé Queue
44
Eso parece horrible. Piense en el esfuerzo adicional que debe realizar si desea insertar una línea en la parte superior o eliminar la línea superior. No puede simplemente eliminar la línea y seguir adelante, debe recordar volver a insertar la llave.
Bryan Oakley
jajaja esto es genial! :) mejor que el primer estilo!
nawfal
Al parecer, incluso tiene un nombre. El Horstman Syyle se menciona en wikipedia . He trabajado con una base de código como esta, realmente no es malo usarla.
AShelly
-1

Todo depende de usted, siempre y cuando no esté trabajando en un proyecto donde el gerente del proyecto haya establecido algunas restricciones de codificación o algunos estándares que todos los programadores que trabajan en ese proyecto deben seguir durante la codificación.

Yo personalmente preferiría el primer método.

Además, no obtuve lo que quieres mostrar con el tercer método.

¿No es esa una manera incorrecta? Por ejemplo, considere una situación como ...

if (you.hasAnswer())
  you.postAnswer();
else
  you.doSomething();

Ahora, ¿qué pasa si alguien quiere agregar algunas declaraciones más en el if bloque ?

En ese caso, si usa el tercer método, el compilador arrojará el error de sintaxis.

if (you.hasAnswer())
   you.postAnswer1();
   you.postAnswer2();
else
   you.doSomething();
Chankey Pathak
fuente
2
Peor aún sería si alguien viniera y lo hiciera: if (you.hasAnswer ()) you.postAnswer (); de lo contrario you.doSomething (); you.doSomethingElse (); - es una receta para errores sutiles que el ojo puede pasar fácilmente y el compilador tampoco ayudará
FinnNk
@FinnNk: ¡Exactamente!
Chankey Pathak
2
Si alguien quiere agregar otra declaración, puede poner los corchetes ellos mismos. Cualquier programador que valga la pena realmente debería ser capaz de resolverlo.
Robert Harvey
Quería decir que su tercer método está mal.
Chankey Pathak
3
@Robert Harvey, he visto a codificadores muy experimentados que no agregan las llaves al modificar el código existente. Creo que el problema es que la sangría es una pista de significado mucho más fuerte que las llaves (especialmente porque hay varios estilos de llaves), por lo que es bastante fácil pasar por alto la llave faltante si la sangría se parece a lo que esperas.
AShelly