En su mayor parte, esta es una preferencia personal, sin embargo, hay algunas cosas que considerar.
Posibles errores
Aunque se puede argumentar que los errores causados por el olvido de las llaves de complemento son raros, por lo que he visto that czafuerza de los animales en la caja de seguridad. they do suceda IOS goto fail error). Así que creo que esto debería ser un factor al considerar el estilo de su código (algunas herramientas advierten sobre engaño-indentación , por lo que también depende de la cadena de herramientas) .
Código válido (que dice que podría ser un error)
Incluso suponiendo que su proyecto no sufra tales errores, al leer el código puede ver algunos bloques de código que parecen que podrían ser errores, pero no lo son, tomando parte de su estado mental ciclos.
Comenzamos con:
if (foo)
bar();
Un desarrollador agrega un comentario útil.
if (foo)
// At this point we know foo is valid.
bar();
Más tarde un desarrollador se expande en él.
if (foo)
// At this point we know foo is valid.
// This never fails but is too slow even for debug, so keep disabled.
// assert(is_valid(foo));
bar();
O agrega un bloque anidado:
if (foo)
while (i--) {
bar(i);
baz(i);
}
O usa una macro:
if (foo)
SOME_MACRO();
"... Ya que las macros pueden definir múltiples líneas de código, ¿la macro usa do {...} while (0)
para múltiples líneas? Debería hacerlo porque está en nuestra guía de estilo, ¡pero es mejor que lo compruebe por si acaso!"
Los ejemplos anteriores son todos códigos válidos, sin embargo, cuanto más contenido haya en el bloque de código, más necesitará leer para asegurarse de que no haya errores.
Tal vez su estilo de código define que los bloques multilínea requieren un corchete (no importa qué, incluso si no son código) , pero he visto este tipo de comentarios agregados en Codigo de producción. Cuando lo lees, existe una pequeña duda de que quien haya editado esas líneas por última vez se olvidó de agregar un refuerzo, a veces siento que la necesidad de volver a verificar funciona como es debido (especialmente cuando se investiga un error en esta área del código ) .
Diff Noise
Una razón práctica para usar llaves para líneas simples es reducir diff noise .
Es decir, cambiando:
if (foo)
bar();
Para:
if (foo) {
bar();
baz();
}
... hace que la línea condicional se muestre en una diferencia a medida que se cambia, esto agrega una pequeña sobrecarga innecesaria.
- las líneas se muestran como cambiadas en las revisiones de código, si sus herramientas de diferenciación están basadas en palabras, puede ver fácilmente que solo se modificó la llave, pero eso toma más tiempo para verificar que la línea no cambió en absoluto . Habiendo dicho eso, no todas las herramientas son compatibles con diffing basado en palabras, diff (svn, git, hg ... etc) se mostrará como si la línea completa hubiera cambiado, incluso con herramientas sofisticadas, a veces es posible que tenga que buscar rápidamente sobre una línea simple basada en diferencias para ver qué ha cambiado.
- las herramientas de anotación (como
git blame
) mostrarán la línea como cambiada, haciendo que el seguimiento del origen de una línea sea más paso para encontrar el cambio real .
Ambos son pequeños y dependen de la cantidad de tiempo que invierta en revisar o rastrear el código de confirmación de las líneas de código cambiadas.
Un inconveniente más tangible de tener cambios de líneas adicionales en una diferencia, su mayor probabilidad de que los cambios en el código causarán conflictos que se fusionan y deben ser resueltos manualmente .
Hay una excepción a esto, para las bases de código que tienen {
en su propia línea, no es un problema.
El argumento diff noise no se mantiene si escribe en este estilo:
if (foo)
{
bar();
baz();
}
Sin embargo, esta no es una convención tan común, por lo que se agrega principalmente a la respuesta para completarla (no sugiero que los proyectos deberían usar este estilo) .