所有编程语言都有布尔短路求值吗?
-
22-07-2019 - |
题
在 PHP 代码中
if(a() && b())
当第一个操作数的计算结果为 false
, b()
不会被评估。
同样,在
if (a() || b())
当第一个操作数的计算结果为 true
, b()
不会评价..
对于所有语言(例如 Java、C# 等)都是如此吗?
这是我们使用的测试代码。
<?php
function a(){
echo 'a';
return false;
}
function b(){
echo 'b';
return true;
}
if(a() && b()){
echo 'c';
}
?>
其他提示
这不是真的为VB6。
在VB.net你必须使用“AndAlso”而不是“和”如果您想要跳过评估第二表达式。
这是适用于所有的语言,如JAVA,C#等?
在C#这仅是为了短路运营商||
'和“&&
”真;如果你只是使用“|
”或“&
”,它会每次评估两侧。
这就是所谓的短路评价和大多数语言做到这一点。在一些语言中存在运营商没有做到这一点。
帕斯卡的原始版本没有,这引起许多痛苦。现代帕斯卡,如Delphi的工作方式相同为C等人
阿达具有条件句的特殊短路形式:
and then
or else
使用这样的:
if p.next /= null and then p.next.name = 'foo'
if x = 0 or else 1/x = y
在某些方面它是一种很好的,因为你可以推断出程序员知道是短路所需要的表达和条件不被意外的工作。
这对于语言是真的,是C的 “孩子”:PHP,Java和C ++,C#,...或者在相同的 “灵感”,如Perl
但它不是VB(至少.NET之前,这引入了新的关键字)真。 点击(这真的打扰你第一次用VB合作^^)的
微软的VBScript (通常所用与“经典” ASP一起)没有为布尔运算符短路评价,而是使用按位评估。这是众多原因,可能是一个最坏的语言永远!
“这是怎么回事是VBScript是 不符合逻辑。 VBScript是按位。所有 所谓逻辑运算符的工作 对数字,而不是布尔值! 不,与,或,异或,当量和所有进出口 其参数转换为四字节 整数,做逻辑运算 每对中的比特的整数,和 返回结果。如果真为-1, 假为0,则一切顺利, 因为-1都有其所有位开启 与0有其所有位关闭。但 如果其他号码在那里,所有的 赌注都关闭。”
这这博客。通过埃里克利珀特。
在的Delphi它是一个编译器选项。
这是真正的Java很好,但运营商|,&等将评估双方
在二郎,所述and
和or
运营商不做短路评价;你如果想短路行为,以便使用orelse
和andalso
运营商。
在标准FORTRAN或Fortran中,布尔表达式的操作数可以以任何顺序进行评价。不完整的评价是允许的,但实现定义。
这使得布尔表达式的优化,如果严格左到右的顺序得到执行,将不会被允许。需要严格的排序表达式必须被分解成单独的条件语句,或依赖于实现的假设可以进行。
由于分解用于强制排序,它遵循单独IF语句不能总是被优化成一个单一的表达。但是,短路评价是明确的分解,这是从来没有比执行严格的左到右的顺序,让懒惰的评价语言更差。
语言WICH从FORTRAN(的Fortran,BASIC,VBn的)衍生的,并且其被设计为实现FORTRAN状效率(帕斯卡,ADA)语言最初随后允许乱序评价的FORTRAN例子。
大多数语言(所有的,我已经看到)上使用条件运算符,如&&和||短路评价。他们将停止作为的条件之一已经满足要求尽快评估。 (第一假上&&。上||第一真)
所有二元操作诸如和|,被处理。 (原始)
所有位运算符诸如和|,被处理。 (编辑:17年5月10日)
这就是所谓的短路评价,这是常见的所有,我在(C,C ++,C#,Java和Smalltalk中,使用Javascript,Lisp的),除了VB,VB.NET和Fortran工作过的语言。
它实际上是一个非常有用的功能。如果没有短路,你将无法做到这一点:
if (a != null && a.isBlank())
如果没有短路,你就必须有嵌套if语句,因为第二部分将抛出一个错误,如果是零。
ColdFusion的将本地做短circut评估。我相信所有的CF开发者写:
<cfif isdefined("somevariable") and somevariable eq something>
//do logic
</cfif>
其他答案给的有和无短路评价语言的好例子,所以我就不再赘述了。
只是一个有趣的一点补充:的Lisp如Clojure的有布尔短路评价,但除此之外,你可以很平凡定义的任何的操作符,你喜欢和短路评价通过使用宏<。 / p>
Clojure中一个短路 “NAND” 操作的示例:
(defmacro nand
([x]
`(not ~x))
([x & xs]
`(let [nand# (not ~x)]
(if nand#
true ; short circuit if we can prove the nand is true
(nand ~@xs))))) ; continue with the other expressions otherwise
(nand true true)
=> false
(nand false (println "Expression with a side effect!"))
=> true