为什么Perl打印一个我不知道的值';在递增之后不期望?

为什么Perl打印一个我不知道的值';在递增之后不期望?,perl,Perl,我正在从命令行运行一行程序: perl -MList::Util=sum -E 'my $x = 0; say sum(++$x, ++$x)' 为什么它说的是“4”而不是“3”?,因为两个增量都是在计算和之前执行的 执行两个命令后,x=2 2 + 2 = 4. 您在同一语句中修改了两次$x。根据,Perl不能保证这些语句的结果是什么。因此它可能是“2”或“0”首先,请记住Perl是通过引用传递的。这意味着 sum(++$x, ++$x) 基本上与 do { local @_;

我正在从命令行运行一行程序:

perl -MList::Util=sum -E 'my $x = 0; say sum(++$x, ++$x)'

为什么它说的是
“4”
而不是
“3”

,因为两个增量都是在计算和之前执行的

执行两个命令后,
x=2

2 + 2 = 4.

您在同一语句中修改了两次
$x
。根据,Perl不能保证这些语句的结果是什么。因此它可能是
“2”或
“0”

首先,请记住Perl是通过引用传递的。这意味着

sum(++$x, ++$x)
基本上与

do {
   local @_;
   alias $_[0] = ++$x;
   alias $_[1] = ++$x;
   ∑
}
Pre increment返回变量本身,而不是它的副本*,因此这意味着
$\u0]
$\u1]
都被别名为
$x
。因此,
sum
可以看到两个参数的当前值
$x
2

经验法则:不要修改和读取同一语句中的值。


*-这没有文档记录,但您会问为什么Perl的行为如此。

文档中的这段内容与此无关。它说没有定义结果,因为没有定义运算符的操作数求值顺序。虽然
+
(在示例中使用)是这样,但逗号运算符(由OP使用)不是这样的。逗号运算符的LHS被记录在RHS之前进行评估。请注意,在这种情况下,Perl也不能保证结果,但原因不同。知道结果取决于知道pre-increment是返回原始(现在已修改)标量,还是返回其副本,而这并没有文档记录。(这是前者,仅供参考。)如果这是原因,那么
sum(+++$x,++$x)
sum(0++++$x,0++$x)
将给出相同的结果。@ikegami不正确,因为表达式
++$x
具有左值性质,但表达式
0++$x
具有右值性质。通常这是不相关的,因为它们被用作右值,但在未定义的情况下,在一个函数调用中执行两个预增量,它恰好具有早期与晚期绑定的效果。@hobbs,你说我说的不是真的,但你继续同意我的观点,即op的左值性质是实际原因。这在我的回答中有详细说明。+1我想你的意思是键入“当前$x的值
(2)
”。另请参见