DOC解释了perl运算符的优先级和关联性。我对->
和*
运营商感兴趣。两者都有left
关联性。
我有下一个例子,似乎->
具有正确的关联性。 未保留作为文档说明:
my @args;
sub call { print "call\n"; shift @args }
sub test { print "test\n"; 1 }
sub t4 { print "t4\n"; 4 }
@args=( \&test, 2, 3 );
call()->( @args, t4 );
sub m1 { print "m1\n"; 2 }
sub m2 { print "m2\n"; 4 }
m1()*(@args, m2);
输出结果为:
t4
call
test
m1
m2
由于->
已离开关联,我希望下一个输出:
call
t4
test
m1
m2
我错过了什么?为什么在t4
之前调用call
?
答案 0 :(得分:4)
您询问操作数评估顺序(评估操作数的顺序),而不是操作员关联性(同一运算符的运算符的顺序)评估优先级。)
许多运营商(包括->
)的操作数评估顺序未定义(或至少未记录)。你会发现它是一致的,但不应该依赖它。
您可以使用语句中断强制所需的顺序:
my $sub = call();
$sub->( @args, t4 );
这也有效:
$_->( @args, t4 ) for call();
关联性是评估相同优先级的运算符的顺序。
例如,*
和/
具有相同的优先级,因此关联性决定了
3 / 4 * 5 * 6
相当于
( ( 3 / 4 ) * 5 ) * 6 = 22.5
而不是
3 / ( 4 * ( 5 * 6 ) ) = 0.025
如您所见,关联性可以直接影响表达式的结果。
操作数评估顺序是评估操作数的顺序。
例如,操作数评估顺序确定1+2
之前是否评估3+4
,反之亦然
( 1 + 2 ) * ( 3 + 4 )
除非评估操作数有副作用(例如更改变量或打印到屏幕),否则操作数评估顺序对表达式的结果没有影响。因此,某些语言未定义以允许优化。
在Perl中,对于许多运营商来说,它是未定义的(或至少是未记录的)。它仅记录以下内容:
,
和=>
):从左到右and
,or
,&&
,||
和//
):左,然后可能正确 [1] < / SUP> ? :
):左,然后是第二或第三 [1] =
):右,然后左 [2] =~
和!~
):左,然后右 [3] my $x = $x;
。答案 1 :(得分:3)
关联性是一条规则,它告诉您如何解析同一运算符出现两次的表达式,或者出现多个具有相同优先级的运算符。例如,关联性确定:
foo()->bar()->baz()
相当于
(foo()->bar())->baz() # left associative
而不是
foo()->(bar()->baz()) # right associative
由于您的代码只包含一个->
运算符,因此该运算符的关联性无关紧要。
您似乎正在寻找有关->
运算符的操作数评估顺序的规则。据我所知,perl中的大多数运算符都没有保证的评估顺序(很像C)。如果顺序很重要,您应该使用显式临时变量将表达式拆分为多个语句:
my $tmp = call();
$tmp->( @args, t4 );
答案 2 :(得分:2)
Associativity描述了处理相同优先级的多个运算符的顺序。它与是否先处理左参数或右参数无关。 ->
左关联意味着a->b->c
被处理为(a->b)->c
,而不是a->(b->c)
。