it-swarm.it

Il modo più leggibile per formattare a lungo se le condizioni?

Se possibile, si dovrebbero evitare le condizioni di if a carica lunga, ma a volte finiamo tutte per scriverle. Anche se è una condizione molto semplice, le dichiarazioni coinvolte sono a volte semplicemente molto prolisse, quindi l'intera condizione finisce per essere molto lunga. Qual è il modo più leggibile per formattarli?

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 altre preferenze?

45
deceze

Spesso, una condizione if lunga è il segno di codice che necessita di refactoring, ma a volte non è possibile evitarlo. In questi casi, preferisco il primo:

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

Perché sei in grado di dire cosa sta succedendo con una riga. Tuttavia, preferirei fare qualcosa del genere, quando possibile:

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

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

Mi piace mantenere gli operatori alla fine per indicare la continuazione:

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

Sono un grande fan di nomi di variabili significativi:

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

if (isInAStrangeCondition) {
    thud();
}

O refactor in funzione, come menzionato sopra.

12
LennyProgrammers

Dico le sottoespressioni più disordinate, o tutte, come variabili bool. Quindi la logica booleana di livello superiore dell'istruzione 'if' può essere chiarita. Nel tipo di lavoro che faccio, non sono sempre diverse le cose ORed o ANDed.

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

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

Questo è particolarmente utile in un debugger, dove posso esaminare tutti i bool prima di eseguire il 'if'.

7
DarenW

Tendo ad allineare gli operatori all'inizio di nuove linee, quindi ricordo come sto combinando i termini (sia per la logica lunga che per l'aritmetica lunga). Come questo:

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

Funziona solo se rientro di 2 spazi o imposto di impostare il mio ambiente in modo da indentare maggiormente i predicati multilinea, altrimenti sarebbe difficile dire dove finisce il predicato e inizia il codice utile.

6
Hoa Long Tam

Sono un fan di quanto segue:

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

In questo modo sembra ancora un'espressione if e non un'espressione if scomposta. Il rientro aiuta a dimostrare che si tratta di una continuazione della riga precedente.

Puoi anche rientrare fino a quando la parentesi aperta non si trova alla fine della riga precedente, in modo che sia alla fine dell'espressione if come dovrebbe essere.

0
EpsilonVector