it-swarm-es.com

¿La forma más legible de formatear mucho si las condiciones?

Las condiciones de bobinado largo if deben evitarse si es posible, aunque a veces todos terminamos escribiéndolas. 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?

45
deceze

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á pasando con una línea. Sin embargo, preferiría hacer algo como esto, cuando sea posible:

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

if (foo()) { ... }
32
user8

Me gusta mantener a 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();
}
21
AShelly

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.

12
LennyProgrammers

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' puede aclararse. 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'.

7
DarenW

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.

6
Hoa Long Tam

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.

0
EpsilonVector