为什么这两段代码会产生不同的输出?
$a = 3;
($a == 4) and print "But I wanted apple, cherry, or blueberry!\n" ;
给出没有程序输出但是
$a = 3;
print "But I wanted apple, cherry, or blueberry!\n" and ($a == 4);
给出:但我想要苹果、樱桃或蓝莓!
为什么这两段代码会产生不同的输出?
$a = 3;
($a == 4) and print "But I wanted apple, cherry, or blueberry!\n" ;
给出没有程序输出但是
$a = 3;
print "But I wanted apple, cherry, or blueberry!\n" and ($a == 4);
给出:但我想要苹果、樱桃或蓝莓!
因为and
是所谓的“短路”算子。这意味着如果您有condition1 and condition2
,则评估第一个条件,并且仅当第一个条件返回 true 时才评估第二个条件。
所以,在
$a = 3;
($a == 4) and print "But I wanted apple, cherry, or blueberry!\n" ;
条件$a==4
为假,因此print
不评估该语句。
然而,在
$a = 3;
print "But I wanted apple, cherry, or blueberry!\n" and ($a == 4);
该print
语句做它的事情并返回true
。评估第二个条件(显然是false
),但打印已经完成。
AND 和 OR 的真值表是
p q p AND q p OR q
- - ------- ------
F F F F
F T F T
T F F T
T T T T
或者如果我们分组,
p q p AND q p q p OR q
- - ------- - - ------
F * F F F F
T F F F T T
T T T T * T
换句话说,并不总是需要评估两个操作数才能知道最终结果。
Perl(以及其他语言)将其作为一个特性结合起来:它将通过尽快返回来“短路”布尔运算符的评估。它不仅是一个很好的优化,而且非常有用。它允许这些构造有意义:
func(...)
or die;
condition(...)
and next;
没有短路,die
将next
无条件评估。
如果要评估两个操作数,则需要临时变量
my $f = f(); # f() has side-effects!
my $g = g(); # g() has side-effects!
if ($f && $g) {
...
}
在 Perl 中,and
是一个短路运算符。
PerlMonks很好地解释了短路运算符:
为什么是“短路”?
Camel II 告诉我们,术语“短路”指的是它们“通过评估尽可能少的操作数来确定语句的真实性”。因此,基本上这些运算符会尽早停止表达式的评估链。这是它们价值的另一个关键。
基本上,如果语句的左侧and
为假,则根本不评估右侧。
如果您不确定优先级(哪些运算符首先运行,哪些运算符最后运行),您总是可以让 Perl 解析您的代码,然后在启用括号的最大使用时再次对其进行反解析:
perl -MO=Deparse,-p -e '($a == 4) and print "But I wanted apple, cherry, or blueberry!\n" ;'
哪个输出:
(($a == 4) and print("But I wanted apple, cherry, or blueberry!\n"));