¿La forma más fácil de formatear mucho si las condiciones? [cerrado]

43

ifDeben evitarse las condiciones de bobinado prolongado si es posible, pero a veces todos terminamos escribiéndolos. Incluso si es una condición muy simple, las declaraciones involucradas a veces son simplemente muy verbales, por lo que toda la condición termina siendo muy larga. ¿Cuál es la forma más fácil de formatear?

if (FoobarBaz::quxQuux(corge, grault) || !garply(waldo) || fred(plugh) !== xyzzy) {
    thud();
}

o

if (
    FoobarBaz::quxQuux(corge, grault)
 || !garply(waldo)
 || fred(plugh) !== xyzzy
) {
    thud();
}

o

if (FoobarBaz::quxQuux(corge, grault)
    || !garply(waldo)
    || fred(plugh) !== xyzzy) {
    thud();
}

o

thudable = FoobarBaz::quxQuux(corge, grault);
thudable ||= !garply(waldo);
thudable ||= fred(plugh) !== xyzzy;

if (thudable) {
    thud();
}

o alguna otra preferencia?

difunto
fuente

Respuestas:

30

A menudo, una condición larga si es el signo de código que necesita refactorización, pero a veces no se puede evitar. En esos casos, prefiero el primero:

if (bar || baz || quux) { ... }

Porque puedes decir lo que está sucediendo con una línea. Sin embargo, preferiría hacer algo como esto, cuando sea posible:

function foo() {
  return bar || baz || quux;
}

if (foo()) { ... }
dorio
fuente
3
desplazarse hacia un lado frente a vertical no es casi la limitación que era en los viejos tiempos ...
Bill
2
y dé un nombre significativo (comercial) a la función para que las personas entiendan lo que se prueba aquí.
Matthieu M.
19

Me gusta mantener los operadores al final para indicar la continuación:

if (the_function_being_called() != RETURNCODE_SUCCESS &&
    the_possibly_useful_recovery_strategy() == RETURNCODE_EPICFAIL &&
    this_user_has_elected_to_recieve_error_reports)
{
    report_error();
}
AShelly
fuente
1
Creo que me gusta este. Utilizo muchos paréntesis para asegurarme de que también puedo entender el orden de precedencia.
Jasarien
55
Prefiero poner los operadores lógicos al comienzo de la línea, de modo que cuando leo una línea, puedo ver fácilmente que es parte del código condicional y no solo una línea regular.
11

Soy un gran admirador de los nombres de variables significativas:

const bool isInAStrangeCondition =
    FoobarBaz::quxQuux(corge, grault) ||
    !garply(waldo) ||
    fred(plugh) !== xyzzy;

if (isInAStrangeCondition) {
    thud();
}

O refactorizar como una función, como se mencionó anteriormente.

LennyProgrammers
fuente
7

Desgloso las subexpresiones más desordenadas, o todas ellas, como variables bool. Entonces, la lógica booleana de nivel superior de la declaración 'if' se puede aclarar. En el tipo de trabajo que hago, no siempre son varias cosas ORed o ANDed.

bool goodblah = some_mess < whatever;
bool frobnacious = messy_crud != junky_expression;
bool yetanother = long_winded_condition;

if (goodblah || (frobnacious && yetanother))   {
    ...
}

Esto es especialmente bueno en un depurador, donde puedo ver todos los bools antes de ejecutar el 'if'.

DarenW
fuente
Esto también me gusta, pero pierdes un beneficio: ya no es posible cortocircuitar las costosas comparaciones.
... Y necesitas ser muy bueno para nombrar toneladas de variables todos los días ...
cronvel
6

Tiendo a alinear los operadores al comienzo de las nuevas líneas, así que recuerdo cómo estoy combinando términos (tanto para lógica larga como para aritmética larga). Me gusta esto:

if (first_attempt(data) == SUCCESS
    || (reusable(data) && second_attempt(data) == SUCCESS)
    || (still_reusable(data) && third_attempt(data) == SUCCESS))
  return SUCCESS;

Esto solo funciona si sangro por 2 espacios o configuro establecer mi entorno para sangrar más predicados multilínea, o de lo contrario sería difícil saber dónde termina el predicado y dónde comienza el código útil.

Hoa Long Tam
fuente
0

Soy fan de lo siguiente:

if (really_long_expression && another_really_really_long_expression && 
            another_very_long_expression_OMG_id_it_long){
    bugs();
}

De esta manera, todavía parece una expresión if y no una expresión if desglosada en pedazos. La sangría ayuda a mostrar que es una continuación de la línea anterior.

También puede sangrarlo hasta que el paréntesis de apertura esté al final de la línea anterior para que esté al final de la expresión if como se supone que debe estar.

EpsilonVector
fuente
1
Me gustó mucho tu método bugs (): D
Joe Phillips