Perl 如何决定计算表达式中的项的顺序?
给定代码:
my $x = 1;
$x = $x * 5 * ($x += 5);
我希望 $x
为 180
:
$x = $x * 5 * ($x += 5); #$x = 1
$x = $x * 5 * 6; #$x = 6
$x = 30 * 6;
$x = 180;
180;
但实际上它是 30
;但是,如果我更改术语的顺序:
$x = ($x += 5) * $x * 5;
我会得到180
。我感到困惑的原因是 perldoc perlop
说得非常清楚:
术语在 Perl 中具有最高优先级。它们包括变量, 引用和类引用运算符、括号中的任何表达式以及任何 其参数带括号的函数。
由于 ($x += 5)
在括号中,因此它应该是一个术语,因此首先执行,无论表达式的顺序如何。
Given the code:
my $x = 1;
$x = $x * 5 * ($x += 5);
I would expect $x
to be 180
:
$x = $x * 5 * ($x += 5); #$x = 1
$x = $x * 5 * 6; #$x = 6
$x = 30 * 6;
$x = 180;
180;
But instead it is 30
; however, if I change the ordering of the terms:
$x = ($x += 5) * $x * 5;
I do get 180
. The reason I am confused is that perldoc perlop
says very plainly:
A TERM has the highest precedence in Perl. They include variables,
quote and quote-like operators, any expression in parentheses, and any
function whose arguments are parenthesized.
Since ($x += 5)
is in parentheses, it should be a term, and therefore executed first, regardless of the ordering of the expression.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
输入问题的行为给了我答案:术语具有最高优先级。这意味着第一段代码中的
$x
被求值并产生1
,然后5
被求值并产生5< /code>,然后对
):($x += 5)
进行求值并产生6
(将$x
设置为$x
会产生副作用code>6同样,第二个示例如下所示:
The act of typing out the question yielded the answer to me: terms have the highest precedence. That means that the
$x
in the first chunk of code is evaluated and yields1
, then5
is evaluated and yields5
, then($x += 5)
is evaluate and yields6
(with a side-effect of setting$x
to6
):Similarly, the second example reduces like this:
每当我对这样的事情感到困惑时,我首先会拿出 perldoc perlop,然后如果我仍然不确定,或者想查看特定代码块将如何执行,我使用 B:: Deparse:
^D
给出:
所以在每个阶段替换值给出:
所以 $x 暂时设置为 6 的事实并没有真正影响任何东西,因为早期的值 (1)已经代入表达式中,到表达式结束时,它现在是 30。
Whenever I have confusion about stuff like this I first pull out perldoc perlop, and then if I'm still not sure, or want to see how a particular block of code will get executed, I use B::Deparse:
^D
gives:
So substituting values at each stage gives:
So the fact that $x was temporarily set to 6 doesn't really affect anything, because the earlier value (1) was already substituted into the expression, and by the end of the expression it is now 30.
$x
本身也是一个术语。由于首先遇到它(在您的第一个示例中),因此首先对其进行评估。$x
by itself is also a TERM. Since it is encountered first (in your first example), it is evaluated first.*
运算符的结合性是向左的,因此最左边的项总是在最右边的项之前计算。其他运算符(例如**
)是右关联的,并且会在语句的其余部分之前计算($x += 5)
。The associativity of the
*
operator is leftward, so the left most term is always evaluated before the right most term. Other operators, such as**
are right associative and would have evaluated($x += 5)
before the rest of the statement.