在Perl中列出运算符优先级

Bri*_*ian 8 perl operator-precedence

我正在阅读"Beginning Perl"一书,它给出了这两个陈述:

print "Test one: ", 6 > 3 && 3 > 4, "\n";
print "Test two: ", 6 > 3 and 3 > 4, "\n";
Run Code Online (Sandbox Code Playgroud)

第一行没有打印任何新行,第二行打印1没有新行.

我对输出感到困惑.根据作者的说法,第二个语句给出了奇怪的输出,因为它就像是说:

print ("Test two: ", 6 > 3) and 3 > 4, "\n";
Run Code Online (Sandbox Code Playgroud)

但是,为什么第一个陈述不一样?我认为它与print的优先级有关.&&具有比打印更高的优先级,因此首先进行评估然后打印.而"和"的优先级低于打印,因此将打印6> 3,打印返回1,然后使用"和"进行评估.然而,这并没有多大意义.

我已经阅读了关于列表运算符的优先级如何工作的Perl文档,但我仍然不理解这个例子.你们可以剖析这两个陈述,告诉我先打印什么吗?您是否也可以解释Perl文档在提到列表操作符为"向左"和"向右"时的含义?谢谢.


非常感谢大家的回答.我现在明白了.我确实在做cjm所说的,并且认为有左右列表操作符.所以现在我明白了它的含义,我理解了整个事情.

hob*_*bbs 12

好的,对于初学者来说:list-operators是perl中优先级最低的东西之一,但只是在他们的右侧.你问这意味着什么:好吧,让我们简单一点.假设有一个名为的listop foo.它的作用并不重要,但它就在那里.你可以轻松地创建这样一个东西,用sub foo { map 10 * $_, @_ }它返回每个参数乘以10.这样做:

print 1, 2, 3;相当于print( 1, 2, 3 );
print foo 1, 2, 3;等于print( foo( 1, 2, 3 ) );
print 1, foo 2, 3;相当于print( 1, foo( 2, 3 ) );

我们可以看到foo在右侧尽可能地吞噬 - 只有声明的结尾(到目前为止......)才能阻止它.如果我们写的@array = (1, foo 2, 3);那相当于@array = (1, foo(2, 3) );因为当然结束周围的括号仍然适用.

由于逗号也是非常低的优先级(就在"List运算符(向右)"之上),我们也可以将我们想要的任何类型的表达式放入listop的参数中 - 这只是perl确保我们不做的方式必须在大多数时候添加括号.数学,按位运算符,比较,甚至正则表达式匹配都具有更高的优先级.

那唯一的东西具有较低的优先级是拼写出逻辑连接词and,or,xor,和not.所以,如果我们写

foo 1, 2, 3 and 4;
Run Code Online (Sandbox Code Playgroud)

这意味着(foo(1, 2, 3) and 4)- foo停止在左边的参数and.这在一个人为的例子中似乎很愚蠢,所以让我们把它变成一个常见的perl习语:

open $fh, '<', $filename or die "$! opening $filename";
Run Code Online (Sandbox Code Playgroud)

这相当于

(open($fh, '<', $filename) or die("$! opening $filename"));
Run Code Online (Sandbox Code Playgroud)

这实际上完全等同于(并编译)

die "$! opening $filename" unless open $fh, '<', $filename;
Run Code Online (Sandbox Code Playgroud)

使用语句修饰符形式unless(根本不是操作符,每个语句只允许一次,并且只出现在语句的末尾,因此它根本不会优先使用,但你可以考虑它作为"低于最低"的优先权向左).

所以无论如何,返回到原始代码示例 - print结束左侧and和右侧的参数and是一个完全独立的逗号表达式 - 它根本不做什么,因为它只是一些常量3 > 4"\n"在void上下文中进行求值.


cjm*_*cjm 8

以下是完整括号中这些语句的外观:

print("Test one: ", ((6 > 3) && (3 > 4)), "\n");
print("Test two: ", (6 > 3)) and ((3 > 4), "\n");
Run Code Online (Sandbox Code Playgroud)

>具有最高的优先级,然后&&,然后,,然后print,然后and.

6 > 3评估为1. 3 > 4求值为false,在Perl中,它是一个特殊值,在数值上下文中为0,但在字符串上下文中为空字符串(如此处).因此((6 > 3) && (3 > 4))产生空字符串.

因此,第一个语句将3个参数传递给print:"Test one: ",空字符串和换行符.它按顺序打印每个参数.

第二个语句只传递2个参数print:"Test two: "1.换行没有打印,因为它从未传递给print.

我不确定如何比文档更好地解释"向左"和"向右" .但也许令你困惑的是,你认为有"向左列表操作"和"向右列表操作".这不是它的意思.它试图说列表运算符右侧的所有内容都被解释为该运算符的参数(除非您点击其中一个非常低优先级的布尔运算符and).但是列表运算符左侧的内容与该列表运算符无关.