2

为什么这两段代码会产生不同的输出?

    $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);

给出:但我想要苹果、樱桃或蓝莓!

4

4 回答 4

7

因为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),但打印已经完成。

于 2012-08-10T03:49:27.120 回答
6

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;

没有短路,dienext无条件评估。

如果要评估两个操作数,则需要临时变量

 my $f = f();  # f() has side-effects!
 my $g = g();  # g() has side-effects!
 if ($f && $g) {
    ...
 }
于 2012-08-10T04:08:09.817 回答
5

在 Perl 中,and是一个短路运算符。

PerlMonks很好地解释了短路运算符:

为什么是“短路”?

Camel II 告诉我们,术语“短路”指的是它们“通过评估尽可能少的操作数来确定语句的真实性”。因此,基本上这些运算符会尽早停止表达式的评估链。这是它们价值的另一个关键。

基本上,如果语句的左侧and为假,则根本不评估右侧。

于 2012-08-10T03:51:06.607 回答
-1

如果您不确定优先级(哪些运算符首先运行,哪些运算符最后运行),您总是可以让 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"));
于 2012-08-10T07:30:51.360 回答