次のうち、物事を行うための好ましい方法はどれですか、そしてその理由は何ですか?関数bar()がいつでも値ゼロをとらないと仮定して、それが違いを生む特定の状況はありますか?
ケース1:両方の条件の真理値をテストする
if ((foo = bar()) && foo < 0)
error();
ケース2:割り当てられた変数のみをテストする
if ((foo = bar()) < 0)
error();
次のうち、物事を行うための好ましい方法はどれですか、そしてその理由は何ですか?関数bar()がいつでも値ゼロをとらないと仮定して、それが違いを生む特定の状況はありますか?
ケース1:両方の条件の真理値をテストする
if ((foo = bar()) && foo < 0)
error();
ケース2:割り当てられた変数のみをテストする
if ((foo = bar()) < 0)
error();
好ましい方法は、それらを分離することです。
foo = bar();
if (foo < 0)
error();
編集:これは、最初のケースのように、読みやすさとバグの回避の両方にとってより良い方法です:
if (foo = bar() && foo < 0)
error();
それはおそらく次のようになります。
if ((foo = bar()) && foo < 0)
error();
最初のものは明らかに間違っています。優先順位規則により、次のようになります。
if (foo = (bar() && foo < 0))
error();
これは通常、期待するものではありません。
すべてではないにしても、ほとんどのコンパイラは、条件付きの余分な括弧内で割り当てを行おうとすると、警告を発行します。
しかし、ほとんどの場合、そのような複合ステートメントは読みにくいと主張しますが、Ruby では意味がありますが、C ではそれほど一般的ではありません。コードレビュー IMO に合格しないという根拠がなければ。
最初の例は機能しますが、誰かが or に変更しようとすると<
爆発<=
し>=
ます: bar
0 を返すと、and ステートメントの最初の部分がテストされ、false と見なされ、2 番目のチェックが中止されます。これは true である必要があります。
また、最初の例は本来の動作を実行しません: の演算子の優先順位=
は より小さい&&
ため、 && 操作の結果の代入を取得しますfoo
だから私は2番目の例を好むでしょう。
ほとんどの場合、それは重要ではありません。最初のケースには冗長性があるため、短さについては 2 番目の提案をお勧めします。
このアプローチが十分でない状況がいくつかあります。特に、変数が共有アセットであるマルチスレッド環境では (設定とテスト操作は非常に一般的です)。この場合、競合やデータの破損を避けるために、変数へのアクセスを適切に保護する (つまり、ロックする) 必要があります。