Najbardziej czytelny sposób formatowania długiego, jeśli warunki? [Zamknięte]

43

ifJeśli to w ogóle możliwe, należy unikać długich warunków nawijania , ale czasem wszyscy je piszemy. Nawet jeśli jest to bardzo prosty warunek, zaangażowane stwierdzenia są czasami po prostu bardzo trudne, więc cały warunek kończy się bardzo długo. Jaki jest najbardziej czytelny sposób ich sformatowania?

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

lub

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

lub

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

lub

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

if (thudable) {
    thud();
}

lub jakieś inne preferencje?

deceze
źródło

Odpowiedzi:

30

Często długi, jeśli warunek jest znakiem kodu, który wymaga refaktoryzacji, ale czasami nie można tego uniknąć. W takich przypadkach wolę pierwszy:

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

Ponieważ jesteś w stanie powiedzieć, co się dzieje za pomocą jednej linii. Jednak wolę raczej zrobić coś takiego, jeśli to możliwe:

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

if (foo()) { ... }
dorycki
źródło
3
przewijanie w bok vs w pionie nie jest prawie ograniczeniem, jakie było w starych, złych czasach ...
Bill
2
i nadaj tej funkcji znaczącą nazwę (biznesową), aby ludzie zrozumieli, co tu przetestowano.
Matthieu M.,
19

Lubię zatrzymywać operatorów na końcu, aby wskazać kontynuację:

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
źródło
1
Myślę, że podoba mi się ten. Stosuję dużo nawiasów, aby upewnić się, że rozumiem również kolejność pierwszeństwa.
Jasarien
5
Wolę umieszczać operatory logiczne na początku wiersza, aby po przeczytaniu wiersza łatwo było zobaczyć, że jest to część warunkowego, a nie zwykłego wiersza kodu.
11

Jestem wielkim fanem znaczących nazw zmiennych:

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

if (isInAStrangeCondition) {
    thud();
}

Lub refaktor jako funkcja, jak wspomniano powyżej.

LennyProgrammers
źródło
7

Przełamuję bałagan podwyrażenia lub wszystkie z nich jako zmienne bool. Następnie można wyjaśnić logiczną logikę najwyższego poziomu instrukcji „if”. W pracy, którą wykonuję, nie zawsze jest kilka rzeczy ORed lub ANDed.

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

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

Jest to szczególnie dobre w debuggerze, w którym mogę sprawdzić wszystkie boole przed wykonaniem „if”.

DarenW
źródło
To też mi się podoba, ale tracisz jedną korzyść: nie jest już możliwe zwieranie kosztownych porównań.
... I musisz być bardzo dobry w nazywaniu ton zmiennych przez cały dzień ...
cronvel 30.08.18
6

Staram się wyrównywać operatory na początku nowych linii, więc pamiętam, jak łączę terminy (zarówno dla długiej logiki, jak i długiej arytmetyki). Lubię to:

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

Działa to tylko wtedy, gdy wcinam o 2 spacje lub ustawiam moje środowisko na wcięcie multilinii predykatów więcej, inaczej trudno byłoby określić, gdzie kończy się predykat i zaczyna się przydatny kod.

Hoa Long Tam
źródło
0

Jestem fanem następujących rzeczy:

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

W ten sposób nadal wygląda jak wyrażenie if, a nie rozbite na kawałki wyrażenie. Wcięcie pomaga pokazać, że jest kontynuacją poprzedniej linii.

Możesz go również wciąć, dopóki nawias otwierający nie znajdzie się na końcu poprzedniej linii, aby znalazł się na końcu wyrażenia if, tak jak powinien.

EpsilonVector
źródło
1
Naprawdę podobała mi się twoja metoda bugs (): D
Joe Phillips