为什么你会在一个条件中使用一个任务?
在许多语言中,作业是合法的。 我从来没有理解这背后的原因。 你为什么要写:
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()返回的错误代码是什么。
原因是 :
-
性能改进(有时)
-
较小的代码(总是)
举一个例子:有一个方法someMethod()
,在if
条件中你要检查方法的返回值是否为null
。 如果没有,你将再次使用返回值。
If(null != someMethod()){ String s = someMethod(); ...... //Use s }
这会妨碍性能,因为你调用了两次相同的方法。 而是使用:
String s; If(null != (s = someMethod())) { ...... //Use s }