条件で割り当てを使用するのはなぜですか?
-
02-07-2019 - |
質問
多くの言語では、割り当ては条件が合法です。私はこの背後にある理由を理解していませんでした。なぜ書くのか:
if (var1 = var2) {
...
}
代わりに:
var1 = var2;
if (var1) {
...
}
解決
if文よりもループに便利です。
while( var = GetNext() )
{
...do something with var
}
それ以外の場合、どちらを記述する必要がありますか
var = GetNext();
while( var )
{
...do something
var = GetNext();
}
他のヒント
関数を呼び出す場合に便利です:
if (n = foo())
{
/* foo returned a non-zero value, do something with the return value */
} else {
/* foo returned zero, do something else */
}
もちろん、n = foo();別のステートメントでif(n)が、上記はかなり読みやすいイディオムだと思います。
多くの場合、エラー検出などを伴う一連のアクションで最も役立ちます。
if ((rc = first_check(arg1, arg2)) != 0)
{
report error based on rc
}
else if ((rc = second_check(arg2, arg3)) != 0)
{
report error based on new rc
}
else if ((rc = third_check(arg3, arg4)) != 0)
{
report error based on new rc
}
else
{
do what you really wanted to do
}
代替(条件で割り当てを使用しない)は次のとおりです。
rc = first_check(arg1, arg2);
if (rc != 0)
{
report error based on rc
}
else
{
rc = second_check(arg2, arg3);
if (rc != 0)
{
report error based on new rc
}
else
{
rc = third_check(arg3, arg4);
if (rc != 0)
{
report error based on new rc
}
else
{
do what you really wanted to do
}
}
}
エラーチェックが長引くと、代替手段はページのRHSを実行できますが、条件付き割り当てバージョンでは実行できません。
エラーチェックは「アクション」でもあります— first_action()
、 second_action()
、 third_action()
—もちろん、単なるチェックではなく。つまり、機能が管理しているプロセスのステップをチェックできます。 (ほとんどの場合、使用するコードでは、関数は前提条件チェックの行に沿っているか、関数が機能するために必要なメモリ割り当て、または同様の行に沿っています)。
作業するデータまたはエラーを示すフラグ(または完了したこと)を返す関数を呼び出す場合に役立ちます。
次のようなもの:
while ((c = getchar()) != EOF) {
// process the character
}
// end of file reached...
個人的には私があまり好きではないイディオムですが、時には代替案はいです。
GCCは、(-Wallを使用して)記述を推奨する場合に、意図せずに割り当てを真理値として使用しようとした場合に検出するのに役立ちます
if ((n = foo())) {
...
}
つまり余分な括弧を使用して、これが本当に必要なものであることを示します。
イディオムは、 if
ステートメントの代わりに while
ループを記述する場合により便利です。 if
ステートメントの場合、説明どおりに分割できます。しかし、この構成要素がなければ、繰り返す必要があります。
c = getchar();
while (c != EOF) {
// ...
c = getchar();
}
またはループアンドハーフ構造を使用します:
while (true) {
c = getchar();
if (c == EOF) break;
// ...
}
私は通常、ループアンドハーフ形式を好むでしょう。
簡単な答えは、表現指向プログラミング言語では、より簡潔なコードを使用できるということです。 クエリからコマンドを分離することを強制しません。
たとえば、PHPでは、SQLデータベースの結果をループするのに便利です。
while ($row = mysql_fetch_assoc($result)) {
// Display row
}
これは:
$row = mysql_fetch_assoc($result);
while ($row) {
// Display row
$row = mysql_fetch_assoc($result);
}
もう1つの利点は、gdbの使用中です。 次のコードでは、シングルステップを実行した場合のエラーコードは不明です。
while (checkstatus() != -1) {
// process
}
むしろ
while (true) {
int error = checkstatus();
if (error != -1)
// process
else
//fail
}
単一のステップで、checkstatus()からの戻りエラーコードが何であるかを知ることができます。
理由は:
-
パフォーマンスの改善(時々)
-
より少ないコード(常に)
例を見てみましょう: someMethod()
というメソッドがあり、 if
条件でメソッドの戻り値が null
。そうでない場合は、戻り値を再度使用します。
If(null != someMethod()){
String s = someMethod();
......
//Use s
}
同じメソッドを2回呼び出すため、パフォーマンスが低下します。代わりに使用します:
String s;
If(null != (s = someMethod())) {
......
//Use s
}