你为什么要在条件下使用作业?

问题描述 投票:67回答:10

在许多语言中,作业在条件上是合法的。我从来不明白这背后的原因。你为什么要写:

if (var1 = var2) {
  ...
}

代替:

var1 = var2;
if (var1) {
  ...
}
variable-assignment condition
10个回答
99
投票

它比if语句更有用于循环。

while( var = GetNext() )
{
  ...do something with var 
}

否则必须写

var = GetNext();
while( var )
{
 ...do something
 var = GetNext();
}

-2
投票

原因是 :

  1. 绩效改善(有时)
  2. 较小的代码(总是)

举一个例子:有一个方法someMethod()并且在if条件下你要检查方法的返回值是否为null。如果不是,您将再次使用返回值。

If(null != someMethod()){
    String s = someMethod();
    ......
    //Use s
}

它会妨碍性能,因为你两次调用相同的方法。而是使用:

String s;
If(null != (s = someMethod())) {
    ......
    //Use s
}

29
投票

如果你正在调用一个函数,它会更有用:

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),但我认为上面是一个相当可读的习语。


29
投票

我觉得它在行动链中最有用,通常涉及错误检测等。

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() - 当然,而不仅仅是检查。也就是说,可以在函数管理的过程中检查它们。 (通常在我使用的代码中,函数沿着前置条件检查,或函数工作所需的内存分配,或类似的行)。


23
投票

如果您正在调用返回要处理的数据的函数或指示错误的标志(或您已完成),那么它将非常有用。

就像是:

while ((c = getchar()) != EOF) {
    // process the character
}

// end of file reached...

就个人而言,这是一个我不太喜欢的习语,但有时替代方案更加丑陋。


10
投票

如果您无意中尝试将赋值用作真值,GCC可以帮助您检测(使用-Wall),以防它建议您编写

if ((n = foo())) {
   ...
}

即使用额外的括号表示这确实是你想要的。


8
投票

当你编写一个while循环而不是if语句时,这个成语更有用。对于if语句,您可以按照描述进行分解。但是如果没有这种结构,你要么必须重复自己:

c = getchar();
while (c != EOF) {
    // ...
    c = getchar();
}

或使用循环结构:

while (true) {
    c = getchar();
    if (c == EOF) break;
    // ...
}

我通常更喜欢循环半形式。


4
投票

简短的回答是Expression-oriented编程语言允许更简洁的代码。他们不会强迫你去separate commands from queries


3
投票

例如,在PHP中,它对于循环SQL数据库结果很有用:

while ($row = mysql_fetch_assoc($result)) {
    // Display row
}

这看起来比以下更好:

$row = mysql_fetch_assoc($result);
while ($row) {
    // Display row
    $row = mysql_fetch_assoc($result);
}

2
投票

另一个优点是在使用gdb期间。在以下代码中,如果我们单步执行,则不知道错误代码。

while (checkstatus() != -1) {
    // process
}

while (true) {
    int error = checkstatus();
    if (error != -1)
        // process
    else
        //fail
}

现在,在单步骤中,我们可以知道checkstatus()的返回错误代码是什么。

© www.soinside.com 2019 - 2024. All rights reserved.