Le moyen le plus lisible de formater long si les conditions? [fermé]

43

Dans la mesure du ifpossible, évitez les longues périodes de bobinage , mais parfois nous finissons tous par les écrire. Même s'il s'agit d'une condition très simple, les déclarations impliquées sont parfois simplement très verbeuses, de sorte que la condition dans son ensemble finit par être très longue. Quel est le moyen le plus lisible de formater ceux-ci?

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

ou

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

ou

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

ou

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

if (thudable) {
    thud();
}

ou d'autres préférences?

décongeler
la source

Réponses:

30

Souvent, une condition longue si est le signe du code qui nécessite une refactorisation, mais il est parfois impossible de l'éviter. Dans ces cas, je préfère le premier:

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

Parce que vous êtes capable de dire ce qui se passe avec une ligne. Cependant, je préférerais de beaucoup faire quelque chose comme ceci, lorsque cela est possible:

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

if (foo()) { ... }
Dorian
la source
3
faire défiler vers le côté ou la verticale n’est pas vraiment la limitation qu’il était à l’époque ...
Bill
2
et donnez un nom significatif à la fonction pour que les gens comprennent ce qui est testé ici.
Matthieu M.
20

J'aime garder les opérateurs à la fin pour indiquer la suite:

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
la source
1
Je pense que j'aime celui-ci. J'utilise beaucoup de parenthèses pour m'assurer de bien comprendre l'ordre de priorité également.
Jasarien
5
Je préfère placer les opérateurs logiques au début de la ligne. Ainsi, lorsque je lis une ligne, je peux facilement voir qu’elle fait partie du conditionnel et non d’une ligne de code normale.
11

Je suis un grand fan de noms de variables significatifs:

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

if (isInAStrangeCondition) {
    thud();
}

Ou refactor en tant que fonction, comme mentionné ci-dessus.

LennyProgrammers
la source
7

Je décompose les sous-expressions plus complexes, ou toutes, sous forme de variables bool. Ensuite, la logique booléenne de niveau supérieur de la déclaration 'if' peut être clarifiée. Dans le genre de travail que je fais, il n’ya pas toujours plusieurs choses ORed ou ANDed.

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

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

Ceci est particulièrement utile dans un débogueur, où je peux regarder toutes les erreurs avant d'exécuter le 'if'.

DarenW
la source
J'aime ça aussi, mais vous perdez un avantage: il n’est plus possible de court-circuiter des comparaisons coûteuses.
... Et vous devez être très bon pour nommer des tonnes de variables tous les jours ...
cronvel
6

J'ai tendance à aligner les opérateurs au début des nouvelles lignes, de sorte que je me souviens de la façon dont je combine les termes (à la fois pour la logique longue et pour l'arithmétique longue). Comme ça:

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

Cela ne fonctionne que si j'indente de 2 espaces ou si je mets mon environnement pour indenter davantage de prédicats multilignes, sinon il serait difficile de dire où finit le prédicat et où commence le code utile.

Hoa Long Tam
la source
0

Je suis fan de ce qui suit:

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

De cette façon, il ressemble toujours à une expression if et non à une expression if décomposée. L'indentation aide à montrer qu'il s'agit d'une continuation de la ligne précédente.

Vous pouvez également l'indenter jusqu'à ce que le crochet d'ouverture se trouve à la fin de la ligne précédente, de sorte qu'il se trouve à la fin de l'expression if telle qu'elle est supposée être.

EpsilonVector
la source
1
J'ai vraiment aimé votre méthode des bugs (): D
Joe Phillips