long if条件をフォーマットする最も読みやすい方法は?[閉まっている]


43

if可能な場合は、長い巻き取り条件を避ける必要がありますが、ときどき私たち全員がそれらを書くことになります。たとえそれが非常に単純な条件であっても、関係するステートメントは時々非常に冗長であるため、条件全体が非常に長くなります。それらをフォーマットする最も読みやすい方法は何ですか?

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

または

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

または

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

または

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

if (thudable) {
    thud();
}

または他の設定?

回答:


30

多くの場合、長いif条件は、リファクタリングを必要とするコードの兆候ですが、場合によっては回避できません。そのような場合、私は最初のものを好む:

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

何が起こっているのかを1行で伝えることができるからです。ただし、可能であれば、次のようなことをしたいです。

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

if (foo()) { ... }

3
垂直対側へのスクロールが...それは悪い昔にあったほとんどの制限ではありません
ビル・

2
そして、機能に意味のある(ビジネス)名を付けて、ここでテストされていることを人々が理解できるようにします。
マチューM.

19

継続を示すために演算子を最後に置くのが好きです:

if (the_function_being_called() != RETURNCODE_SUCCESS &&
    the_possibly_useful_recovery_strategy() == RETURNCODE_EPICFAIL &&
    this_user_has_elected_to_recieve_error_reports)
{
    report_error();
}

1
私はこれが好きだと思います。優先順位も理解できるように、多くの括弧を使用しています。
ジャサリアン

5
論理演算子を行の先頭に配置することをお勧めします。行を読むと、コードの通常の行ではなく、条件の一部であることが簡単にわかります。

11

私は意味のある変数名の大ファンです:

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

if (isInAStrangeCondition) {
    thud();
}

または、前述のように、関数としてリファクタリングします。


7

メッセンジャーの部分式、またはそれらすべてをブール変数として分割します。次に、「if」ステートメントのトップレベルのブール論理を明確にすることができます。私がやるような仕事では、常にいくつかの事柄が論理和や論理積をとられているわけではありません。

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

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

これは、デバッガーで特に優れています。デバッガーでは、「if」を実行する前にすべてのブール値を確認できます。


私もこれが好きですが、あなたは1つの利点を失います:もはや高価な比較を短絡することはもうできません。

...そして、あなたは
一日中

6

私は新しい行の先頭で演算子を揃える傾向があるので、用語を結合する方法を覚えています(長いロジックと長い演算の両方)。このような:

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

これは、2スペースでインデントするか、環境を設定して複数行の述語をさらにインデントするように設定した場合のみ機能します。


0

私は次のファンです。

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

このように、それはif式のように見えますが、分割されたif式ではありません。インデントは、前の行の続きであることを示すのに役立ちます。

また、開始ブラケットが前の行の最後になるまでインデントして、想定どおりif式の最後になるようにすることもできます。


1
私はあなたのbugs()メソッドが本当に好きでした:D
ジョー・フィリップス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.