Declaración simple si bloque - llaves o no? [cerrado]

59

¿Cuál es mejor / más generalmente aceptado?

Esta:

if(condition)
{
  statement;
}

O:

if(condition)
  statement;

Tiendo a preferir el primero, porque creo que hace que sea más fácil saber qué pertenece realmente en el bloque if, evita que otros agreguen las llaves más tarde (o crean un error al olvidarlo), y hace que todas sus declaraciones if uniforme en lugar de algunos con tirantes y otros sin. El segundo, sin embargo, sigue siendo sintácticamente correcto y definitivamente más compacto. Sin embargo, tengo curiosidad por ver cuál es el más preferido por otros.

Zannjaminderson
fuente
2
Pero tienes tu llave de apertura en la posición incorrecta. Eso es seguro.
Christian Mann
En muchos idiomas, un bloque es una declaración, por lo tanto, sintácticamente, siempre es una declaración if (expresión)
Ingo
2
Como no especificaste un idioma ... ¿Qué pasa statement if condition;?
Dave Sherohman
@Christian: buena. Esa sería otra pregunta aparte de esto, ¿no?
Zannjaminderson
@Ingo - buen punto.
Zannjaminderson

Respuestas:

131

El primero es mejor porque el segundo es propenso a errores. Por ejemplo, supongamos que está comentando temporalmente el código para depurar algo:

if(condition) 
//      statement;
otherStatement;

O agregando código a toda prisa:

if(condition) 
    statement;
    otherStatement;

Esto es obviamente malo. Por otro lado, el primero se siente demasiado detallado a veces. Por lo tanto, prefiero poner todo en una línea si es lo suficientemente corto y simple:

if(condition) statement;

Esto reduce el ruido sintáctico mientras hace que la construcción parezca que hace lo que realmente hace, por lo que es menos propensa a errores. Siempre que esta sintaxis solo se use para declaraciones y condiciones muy simples y cortas, me parece perfectamente legible.

dsimcha
fuente
35
Buen punto sobre poner todo en una línea.
Neil Aitken
77
@artjomka: Si la declaración es larga y tiene que ir en su propia línea, entonces uso llaves para facilitar la lectura. El punto es que desea la construcción más corta y menos ruidosa sintácticamente que sea inequívoca para un humano que la está leyendo rápidamente en lugar de examinarla.
dsimcha 03 de
15
Prefiero el que tiene llaves por las razones ya mencionadas. No me gusta el one-liner, porque no es inmediatamente obvio lo que sucede cuando paso por encima de la línea en el depurador. Tengo que dar un paso separado para ver a qué condición se evalúa.
Jim A
10
El espacio en blanco de @TMN es gratuito, los monitores son grandes y su cerebro aprende a reconocer la forma que le ayuda a analizar el código.
Murph el
55
@Murph: el espacio en blanco es gratis? Debo haber perdido eso. En mi pantalla, ocupa mucho espacio. Mucho más del 50% en realidad. Lo cual en mi libro parece un gran desperdicio. Personalmente, me gusta maximizar el contenido por centímetro cuadrado en el código.
Konrad Rudolph el
44

Siempre uso corchetes solo para estar seguro.

Está bien cuando lo escribes, pero sabes que alguien vendrá en el futuro e insertará otra declaración sin poner corchetes.

Neil Aitken
fuente
20
¿La gente realmente ha visto que esto suceda? No creo haber visto esto en 10 años de programación. Tal vez he estado demasiado protegido. :)
David
99
Me encantaría decir que no, pero lamentablemente lo he visto.
Neil Aitken el
13
Siempre usa corchetes para que nunca se olvide de usar corchetes, es tan simple como eso.
Murph el
12
+1 a @Murph. La misma razón por la que uso mis intermitentes cuando no hay nadie cerca, ¡y en estacionamientos!
Dan Ray el
77
Esta es una buena práctica para ayudar a prevenir errores al fusionar de rama a tronco o entre ramas.
JBRWilkinson el
27

Prefiero la versión sin llaves cuando sea posible.

La siguiente explicación es larga. Por favor, tenga paciencia conmigo. Daré una razón convincente para que prefiera este estilo. También explicaré por qué creo que el contraargumento habitual no es válido.

Las líneas (casi) vacías son un desperdicio

La razón de esto es que la llave de cierre requiere una línea adicional de código, y también la llave de apertura, según el estilo. 1

¿Es esto un gran problema? Superficialmente, no. Después de todo, la mayoría de las personas también ponen líneas vacías en su código para separar bloques lógicamente ligeramente independientes, lo que mejora enormemente la legibilidad.

Sin embargo, detesto desperdiciar el espacio vertical. Los monitores modernos en realidad tienen un amplio espacio horizontal. Pero el espacio vertical sigue siendo muy, muy limitado (a menos que use un monitor en posición vertical, lo que no es tan raro). Este espacio vertical limitado es un problema: se reconoce ampliamente que los métodos individuales deben ser lo más cortos posible y que los corchetes correspondientes (u otros delimitadores de bloque) no deben tener más de una altura de pantalla en la diferencia para que pueda ver todo el bloque sin desplazamiento

Este es un problema fundamental : una vez que ya no puede ver todo el bloque en su pantalla, se vuelve difícil de comprender.

Como consecuencia, detesto las líneas vacías redundantes. Donde las líneas vacías individuales son cruciales para delimitar bloques independientes (solo mire la apariencia visual de este texto), las líneas vacías consecutivas son un estilo muy malo en mi libro (y en mi experiencia generalmente son un signo de programadores novatos).

Del mismo modo, las líneas que simplemente sostienen una llave, y que podrían economizarse, deberían serlo. Un bloque de una sola declaración que está delimitado por llaves desperdicia una o dos líneas. Con solo 50 líneas por altura de pantalla, esto es notable.

Omitir aparatos ortopédicos tal vez no haga daño

Solo hay un argumento en contra de omitir llaves: que alguien más tarde agregará otra declaración al bloque en cuestión y olvidará agregar las llaves, cambiando así inadvertidamente la semántica del código.

De hecho, esto sería un gran problema.

Pero en mi experiencia, no lo es. Soy un programador descuidado; y, sin embargo, en mi década de experiencia en programación, honestamente puedo decir que he no una vez olvidado de añadir las llaves cuando se añade una declaración adicional a un bloque de Singleton.

Incluso me parece inverosímil que esto sea un error común: los bloques son una parte fundamental de la programación. La resolución y el alcance del nivel de bloque es un proceso mental automático e integrado para los programadores. El cerebro simplemente lo hace (de lo contrario, razonar sobre la programación sería mucho más difícil). No se requiere un esfuerzo mental adicional para recordar poner los frenos: el programador también recuerda sangrar correctamente la declaración recién agregada, después de todo; entonces el programador ya ha procesado mentalmente que hay un bloque involucrado.

Ahora, estoy no diciendo que la omisión de los apoyos no causa errores. Lo que digo es que no tenemos evidencia de una manera u otra. Simplemente no sabemos si causa daño.

Entonces, hasta que alguien pueda mostrarme datos concretos, recopilados de experimentos científicos, que demuestren que esto es realmente un problema en la práctica, esta teoría sigue siendo una " historia justa ": una hipótesis muy convincente que nunca se ha puesto a prueba, y que debe no ser utilizado como un argumento.


1 Este problema a veces se resuelve poniendo todo, incluidos los corchetes, en la misma línea:

if (condition)
{ do_something(); }

Sin embargo, creo que es seguro decir que la mayoría de las personas desprecian esto. Además, tendría los mismos problemas que la variante sin llaves, por lo que es el peor de ambos mundos.

Konrad Rudolph
fuente
66
Omitir llaves daña la legibilidad y puede causar problemas fácilmente cuando se modifica el código.
Josh K
15
@Josh: el primer reclamo es ridículo, ya que muestran lenguajes como Python (respaldarlo con evidencia si crees lo contrario). El segundo ha sido contrarrestado en mi respuesta. ¿Tienes evidencia que lo respalde? De lo contrario, su comentario es una indicación de que realmente no ha leído mi texto. Hazlo antes de criticarlo.
Konrad Rudolph el
8
+1 por tus pensamientos, pero creo que tu posición es contraproducente. Dices "muéstrame datos concretos, recopilados de experimentos científicos, que demuestren que esto es realmente un problema en la práctica" y, sin embargo, recurren a la experiencia anecdótica (propia) para defender su posición. Usted dice: "en mi experiencia ... en mi década de experiencia ... me parece inverosímil ..." y así sucesivamente. ¿Puede mostrar datos concretos, recopilados de experimentos científicos, que respalden su afirmación, "Omitir llaves no hace daño"? La experiencia personal está bien cuando se apoya una opinión, pero no pida más "evidencia" de la que está dispuesto a dar.
bedwyr
3
@bedwyr: sin embargo, hay una diferencia cualitativa. Primero, dejo en claro que los datos me persuadirán, y dejo igualmente claro que la mía es simplemente una hipótesis, no respaldada por datos. En segundo lugar, he establecido un argumento (al menos para mí) plausible para mi creencia de que el reclamo es falso y por qué debe ser corroborado. Lo que me lleva a la tercera: la responsabilidad aquí está en la oposición para probar su reclamo, no en mí para refutarlo. Y además del problema de plausibilidad, he mostrado un argumento fáctico no relacionado que respalda mi estilo de codificación.
Konrad Rudolph el
44
@Konrad: python no muestra lo contrario porque la sangría es significativa y, por lo tanto, las llaves están implícitas. Los buenos programadores brillantes, del tipo que están aquí, probablemente no cometerán el error a menudo si es que lo hacen (en muchos años probablemente haya tenido problemas solo en un par de ocasiones), pero hay muchos menos buenos programadores que hacen cosas estúpidas, que es una de las razones por las cuales se necesitan estándares de codificación en primer lugar. (Y debido a que los plazos y el estrés pueden hacer que lo mejor de nosotros sea menos bueno).
Murph el
19

Voy con el segundo. Es más sucinto y menos detallado.

Intento no escribir en el mínimo común denominador, por lo que espero que otros desarrolladores sepan cómo escribir una de las estructuras de flujo de control más comunes en la programación actual.

Steven Evers
fuente
11
¡absolutamente! después de todo, si el código era difícil de escribir, ¡también debería ser difícil de mantener! ;-)
Steven A. Lowe
3
@ Steven Si te olvidas de llaves, creo que hay otros problemas aquí.
TheLQ
más succint == menos detallado
UncleZeiv
55
@SnOrfus: algo sarcástico, ya que los 2 caracteres adicionales son triviales y evitan un error de mantenimiento muy común. Su millaje puede variar ;-)
Steven A. Lowe
1
Para mí, la sangría deja en claro lo que está sucediendo. La primera forma quema espacio extra en la pantalla y, por lo tanto, es negativo para mí.
Loren Pechtel
16

Usaría lo siguiente (el consenso aquí):

if (condition) {
    any_number_of_statements;
}

También es posible:

if(condition) single_compact_statement;

No tan bueno, especialmente en C / C ++ - como lenguajes:

if(condition) 
    single_compact_statement;

(No hay elección aquí en Python ;-)


En Perl , usarías:

$C = $A**3 if $A != $B;

o

$C = $A**3 unless $A == $B;

(Esto no es pseudocódigo ;-)

botas de goma
fuente
1
Mis pensamientos exactamente. Si la declaración única se ve bien en una sola línea después de la ifcláusula, no uso llaves. Para cualquier otra ifdeclaración (o cualquier declaración que use varias líneas), siempre uso llaves. En particular, si hay una elsecláusula, cada caso siempre tiene llaves.
eswald 03 de
99
Nunca antes había visto a alguien confundir a Perl con un pseudocódigo. Caracteres aleatorios sí, pseudocódigo - no.
Joe D
3
Me pregunto si alguien ha creado un generador de programas Perl simplemente conectando / dev / random a un intérprete Perl ...
Christian Mann
Me gusta el enfoque de Ruby aquí. Ofrece el estilo perl de una sola línea <statement> if <condition>o un estilo de bloque multilínea if <condition>/ <do something>/ end(ruby evita los corchetes, por lo que aquí el corchete inicial está implícito ify el corchete final se reemplaza por un literal end). Ni siquiera ofrece la extraña declaración if de varias líneas, pero realmente solo una sola línea.
Ben Lee
El one-liner no funciona con la mayoría de los depuradores (no es posible desencadenar una interrupción cuando el contenido de la cláusula 'if' está a punto de ejecutarse).
Peter Mortensen
11

Utilizo el método de llaves - por todas las razones anteriores más una más.

El código se fusiona. Se sabe que sucede en proyectos en los que he trabajado en esa declaración única si se han roto por fusiones automáticas. Lo que da miedo es que la sangría se ve bien a pesar de que el código es incorrecto, por lo que este tipo de error es difícil de detectar.

Así que voy con aparatos ortopédicos, en sus propias líneas. Es más fácil detectar los niveles de esa manera. Sí, desperdicia espacio en pantalla vertical y eso es un verdadero inconveniente. Sin embargo, creo que vale la pena.

usuario36294
fuente
10

Sin frenos. Si algún otro programador agrega una segunda declaración a mi código, no es más culpa mía que si dejo que alguien conduzca mi automóvil y se caiga por un precipicio.

Covar
fuente
3
¡Exactamente! No es nuestra culpa que él / ella no conozca la sintaxis.
kirk.burleson
3
Mal ejemplo. Uno bueno es un automóvil con pedales extraviados: gasolina en lugar de frenos. Es tu auto, así que no te importa nadie más. Es un problema que no sepan sobre su posición única de los pedales. ¿Eres un buen ingeniero de automóviles en este caso?
yegor256
Sería tu culpa si les entregaras tu auto sabiendo que pueden estar borrachos. Del mismo modo, debemos tratar de asumir lo menos posible acerca de futuros desarrolladores para ayudar a facilitar el mantenimiento.
Aram Kocharyan
8

Hemos tenido este argumento más de una vez aquí, y el consenso general es usar siempre llaves. Las razones principales son sobre legibilidad / mantenibilidad.

Si necesita agregar código al ifbloque, no necesita recordar / buscar llaves. Cuando los futuros programadores leen el código, las llaves siempre son inequívocas.

En el lado positivo, ReSharper agregará automáticamente las llaves para programadores perezosos en Visual Studio, y supongo que hay complementos para otros IDE que también lo harán.

shimonyk
fuente
3
Categóricamente no compro el reclamo de legibilidad. Python es uno de los lenguajes más legibles que existen y no necesita delimitadores. Esa afirmación simplemente no es cierta. Tampoco compro el reclamo de mantenibilidad porque hasta ahora no está probado y aún se ha vuelto a compartir repetidamente. Pero en este caso estoy realmente muy interesado en la evidencia empírica. Esto es algo que un estudio podría descubrir fácilmente y resolver de una vez por todas.
Konrad Rudolph el
Como Python usa sangría en lugar de delimitadores, está implícito que no es una comparación válida.
Murph el
@Konrad: evidencia empírica: cuando era un nuevo programador, personalmente agregué código a un bloque if sin llaves sin darme cuenta de que el programador anterior no se había molestado con las llaves. Personalmente, he visto a otras personas hacer esto con mis propios ojos. De acuerdo, solo una vez vi que alguien necesitaba ayuda para encontrar el problema después de ejecutar su código, pero eso tenía más que ver con las malas habilidades de prueba.
shimonyk el
@shimonyk: entonces, ¿básicamente sus observaciones respaldan mi afirmación de que este problema es intrascendente? Por cierto, las observaciones personales son anécdotas, no cuentan como evidencia empírica.
Konrad Rudolph el
@Konrad muy bien, por favor cita tus fuentes también. ¿Supongo que tiene un estudio doble ciego revisado por pares al que hace referencia? Si no es así, simplemente burlar sus propias anécdotas en un intento de demostrar que otros están equivocados y exigir que otro afiche se refiera a 'evidencia' es hipócrita en el mejor de los casos. Como alguien más abajo sobre este mismo tema escribió "la responsabilidad aquí está en la oposición para probar su reclamo, no en mí para refutarlo".
shimonyk el
7

Yo uso la primera sintaxis, casi sin excepción. Porque no se puede malinterpretar .

"No me hagas pensar" no solo se aplica a las interfaces de usuario, ustedes ;-)

Steven A. Lowe
fuente
44
Solía ​​hacer esto, pero me convenció el argumento de que los programadores necesitan saber el idioma y que se les debe hacer pensar.
kirk.burleson
2
Lo considero una cortesía común ... para mi futuro yo.
Steven A. Lowe
5

Yo personalmente prefiero el segundo. El primero se ve feo, incómodo y desperdicia espacio horizontal. Los principales problemas con el segundo son las macros y las personas que modifican su código en un momento posterior y lo interpretan mal.

A esto, digo "no use macros". También digo, "sangra tu maldito código correctamente". Teniendo en cuenta cómo cada editor de texto / IDE utilizado para la programación sangra automáticamente, esto no debería ser tan difícil de hacer. Al escribir código en Emacs, usaría la sangría automática para identificar si escribí algo incorrecto en una línea anterior. Cada vez que Emacs comienza a arruinar la sangría, generalmente sé que he hecho algo mal.

En la práctica, termino siguiendo la convención de codificación que se me ha presentado. Pero estos me molestan (y me hace mucho más feliz cuando codifico en Python y todo este desastre de soporte desaparece):

if (condition) {
    statement;
} // stupid extra brace looks ugly

Entonces

if (condition) // the brackets have now just become noise
{ statement; } // also can't see the indentation, harder to read

Aunque honestamente, dos declaraciones en una declaración if me molestan mucho más que una sola declaración. Principalmente porque entonces se requieren paréntesis y todavía se ve divertido con solo dos declaraciones en la declaración if.

jsternberg
fuente
Si va a escribir macros, debe escribirlas para asegurarse de que puedan insertarse en cualquier parte del código sin romperse de todos modos.
Covar
4

Yo uso la versión de dos líneas sin llaves (la segunda forma), pero no para ahorrar espacio.

Utilizo ese formulario porque lo encuentro más legible, visualmente más atractivo y más fácil de escribir. Solo uso ese formulario si se cumplen esas condiciones; es decir, la ifcondición tiene que encajar bien en una sola línea, y la declaración correspondiente tiene que encajar bien en la siguiente línea. Si ese no es el caso, usaré llaves para mejorar la legibilidad.

Si uso este formulario, me aseguro de que haya una línea vacía (o una línea que contenga solo una llave) antes y después de la ifdeclaración (o arriba del comentario, si está presente). Si bien esto no es una regla que sigo conscientemente, lo noto ahora después de leer esta pregunta.

Conservar el espacio de la pantalla no es una prioridad para mí. Si necesitara más espacio, usaría un monitor más grande. Mi pantalla ya es lo suficientemente grande como para leer cualquier cosa en la que deba centrar mi atención. Es poco probable que necesite centrarme en tantas líneas de código a la vez que ocupen toda mi pantalla. Si hay tanto anidamiento con un fragmento de código que no puedo entenderlo sin ver más de una vez, entonces tendría que considerar si la lógica podría representarse mejor mediante la refactorización.

A continuación hay algunos ejemplos que demuestran cómo uso esta forma de la ifdeclaración.

    string GuardConditions(Plan planForWorldDomination)
    {
        if (planForWorldDomination == null)
            throw new ArgumentNullException("planForWorldDomination");

        if (!planForWorldDomination.IsComplete())
            return "Doh!";

        planForWorldDomination.Execute();
    }

    void ProcessingLogic()
    {
        OneBlankLineAbove();

        if (simpleCondition)
            simpleStatement();

        OneBlankLineBelow();
        OneBlankLineAbove();

        // optional comment on the line above an if statement
        if (simpleCondition)
            simpleStatement();

        OneBlankLineBelow();
    }

    void Assignment(string drive)
    {
        OneBlankLineAbove();

        string prompt;
        if (simpleCondition)
            prompt = "simple assignment";
        else
            prompt = null;

        OneBlankLineBelow();
    }

    string Return()
    {
        OneBlankLineAbove();

        if (simpleCondition)
            return "simple return";
        else
            return null;

        OneBlankLineBelow();
    }
Aprendiz del Dr. Wily
fuente
3

Tirantes. Siempre. Soy un poco fanático de ellos, porque le da al código algo de consistencia. Y también, como escribió @dsimcha, hay menos posibilidades de errores al agregar líneas de código adicionales.

La "fealdad" de las llaves alrededor de una sola línea de código es menos dañina que el trabajo adicional que es probable en aquellos casos con depuración y / o agregando código.

Vedran Krivokuća
fuente
1
Nunca he visto a nadie cometer el error del que estás hablando.
kirk.burleson
1
Acabo de llegar ayer en otra pieza de código. :-) Me pregunto cómo se verá el upstream, entre otras adiciones al código, agregando llaves en todos sus if's porque realmente parece ser de un lado diferente al mío en esto. :-) (cálmate, estoy bromeando,
edité
2

Personalmente voy con corchetes.

¿Por qué?

Bueno, si alguien viene y necesita agregar código en la declaración if, está 100% claro dónde está el alcance.

Mantiene el formato de las ifdeclaraciones consistentes sin importar cuántas declaraciones haya en el bloque.

Sin embargo, si el estilo del proyecto es irse, quédese con eso.

ChrisF
fuente
1

Casi siempre uso los soportes solo para estar seguro. Sin embargo, a veces, si el contenido del bloque es realmente corto, lo dejaré y lo haré de una sola línea de esta manera:

if (x==5) Console.WriteLine("It's a five!");
JohnFx
fuente
Supongo que alguien no es fanático de la brevedad.
JohnFx
2
Brevedad en aras de la legibilidad? Absolutamente no. Es código, no un concurso de golf.
Josh K
3
Creo que la legibilidad es una gran razón para la brevedad, personalmente. En cualquier caso: el espacio en blanco no cuenta en mi libro de reglas de código de golf.
JohnFx
El único problema con esto es que se presta para abusar
Conrad Frix el
2
Entonces no abuses de ello. No digo que lo use como un estándar de codificación. Sucede que muchas veces tienes un condicional realmente corto seguido de una sola declaración muy corta y esto funciona bien. Por ejemplo, un if (afirmar) log.write ("aserción fallida");
JohnFx
1

Prefiero llaves para la consistencia, pero no desperdiciar demasiado espacio en blanco (por lo que el código con formato más legible está en mi campo de visión limitado). Entonces escribo esto para líneas lo suficientemente cortas:

If (cond) { statement; }
hotpaw2
fuente
Interesante, realmente no veo código como este, pero me gusta un poco.
Thomas Eding
0

Usualmente uso llaves, pero hay algunos casos en los que no.

object GetObject() {
    // calculate obj1
    if(obj1 != null)
        return obj1;

    // calculate obj2
    if(obj2 != null)
        return obj2;

    // calculate obj3
    if(obj3 != null)
        return obj3;

    return defaultObj;
}

Para mí, sería una tontería agregarlos allí. Si alguien agrega una declaración después del return, tenemos mayores problemas que problemas de alcance.

Nota para uno mismo - piense en un nombre
fuente
Podrías usarlo con la misma facilidadreturn (obj != null) ? obj : "Error";
Josh K
@ Josh, ver edición
Nota personal - piense en un nombre el
En ese caso, usaría algo como Object returnObj = defaultObj; /* Three else-if's to change it to obj1/2/3 */ return returnObj;.
Josh K
@ Josh, lea stackoverflow.com/questions/36707/… . Primer comentario sobre la primera respuesta: "Aunque tener un punto de salida múltiple puede salirse de control, definitivamente creo que es mejor que poner toda su función en un bloque IF ".
Nota personal: piense en un nombre el
0

Si el IDE tiene formato de código disponible, no uso llaves.

Por otro lado, cuando el código se puede editar en otros editores que no admite el formateo automático, es peligroso no poner llaves como se menciona en otras publicaciones. Pero aun así prefiero no usar aparatos ortopédicos, y no ha sido un problema para mí.

nimcap
fuente