所以这里是
$y = 0 | 2 | 4; # answer is 6
$x = 0 || 2 || 4; # answer is 2
我知道为什么$y
是6
,因为它在每个数字和2 | 4 = 6
上使用OR
运算符,但对于$x
......
为什么2
?
因为 2 是第一个非伪造项目,并且逻辑 OR 短路。 它计算为假的零,然后计算不假的 2,因此完成并返回 2。 请考虑以下示例的输出:
$val = 1;
sub a_proc {
print "a_proc: ", $val++, "n";
1;
}
$another_val = &a_proc || &a_proc;
这将输出a_proc: 1
. 一旦a_proc
返回一个 true 值,解释器就可以停止计算,因为逻辑 OR true
并且任何值都是true
的。
它是一个短路的、保值的逻辑或。 基本上,它依次评估||
之间的每个事物,直到找到一个不假的东西,此时它返回该操作数并且不计算任何后续操作数。
编辑
perl 的逻辑操作有两个重要特性
-
它们是短路的,因为它们首先计算左操作数,如果它是真的(对于
&&
为假),则不计算右操作数 -
它们是值保留的,因为它们将操作数转换为用于连接数的布尔值 true 或 false(并确定是否计算正确的操作数),但表达式的结果是转换为布尔值之前的原始值
这两个特性都非常重要,它们结合起来使||
在perl中特别有用 - 比在C/C++中更有用,在C/中它只是短路而不是值保留。
虽然运算符看起来相似,但它们的目的实际上是不同的。
来自perldoc perlop:
二进制"||"执行短路 逻辑或操作。也就是说,如果 左操作数为真,右操作数为真 甚至不计算操作数。
与以下相比:
二进制 "|" 返回其操作数 ORed 一点一滴地在一起。
||
的目的是想出一个答案"x || y
是真的还是假的?",而bitwise or
的目的是——|
——是想出一个操作数的乘积(?),或者类似"x | y
的结果是什么?
由于||
唯一有趣的两个结果是真或假,因此该陈述可以(并且正在)短循环,从而造成这种效果。
在第一条声明中:(0 | 2) = 2, (2 | 4) = 6
在第二条声明中:(0 || 2) = 2, (2 || ...) = 2
有趣的是,bitwise or
在二进制数内设置布尔值。在数字的二进制表示形式中的仓位上添加真值或假值。
0000 | 0010 = 0010
0010 | 0100 = 0110
0110 | 0001 = 0111
0111 | 0001 = 0111 # no change
这对于在一个数字中存储多个布尔值非常方便,可以用&
(bitwise AND
)进行检查。
0101 & 0100 = 0100 (true)
0101 & 0010 = 0000 (false)
有10种人:懂二进制数的人和不懂二进制数的人。
EXPR_A || EXPR_B
或多或少等同于
do { my $rv = EXPR_A; if ($rv) { $rv } else { EXPR_B } }
或用英语,
- 首先,它在标量上下文中评估EXPR_A。
- 如果值为 true,则返回此值。
- 如果值为 false,则计算并返回EXPR_B。
有时你会看到它们被锁住。
EXPR_A || EXPR_B || EXPR_C || EXPR_D
只是
( ( EXPR_A || EXPR_B ) || EXPR_C ) || EXPR_D
因此,只需递归应用上述内容即可。
你最终得到返回 true 的第一个表达式的结果,如果没有一个表达式为真,则得到最后一个表达式的结果。