为什么你会在一个条件中使用一个任务?

在许多语言中,作业是合法的。 我从来没有理解这背后的原因。 你为什么要写:

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

如果您调用一个返回要处理的数据的函数或一个指示错误(或已完成)的标志,那么它会很有用。

就像是:

 while ((c = getchar()) != EOF) { // process the character } // end of file reached... 

就个人而言,这是一个我不太喜欢的习惯用语,但有时候更为丑陋。

我发现它经常涉及错误检测等行为链条最有用。

 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 } 

替代scheme(不使用条件中的任务)是:

 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运行,而条件赋值版本则不能这样做。

这个习语在写while循环而不是if语句时更有用。 对于if语句,您可以按照您的描述将其分解。 但是如果没有这个构造,你可能不得不重复自己:

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

或者使用循环半结构:

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

我通常更喜欢循环半的forms。

GCC可以帮助你检测(有-Wall),如果你无意中尝试使用一个赋值作为真值,万一它build议你写

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

即使用额外的括号来表明这真的是你想要的。

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

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

这看起来好于:

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

简而言之, 面向expression式的编程语言允许使用更简洁的代码。 不要强迫你从查询中分离出命令 。

另一个好处是在使用gdb的时候。 在下面的代码中,如果我们单步执行,错误代码是不知道的。

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

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

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

原因是 :

  1. 性能改进(有时)

  2. 较小的代码(总是)

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

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

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

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