我将问题缩小到此代码
$a = 3;
$a = 3 * $a++;
echo $a; //9
$a = 3;
$a = $a * $a++;
echo $a; //12
这是第一次操作的VLD操作码
compiled vars: !0 = $a
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 3
3 1 POST_INC ~2 !0
2 MUL ~3 ~2, 3
3 ASSIGN !0, ~3
4 4 ECHO !0
5 5 > RETURN 1
对于第二次操作($ a * $ a++)
compiled vars: !0 = $a
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 3
3 1 POST_INC ~2 !0
2 MUL ~3 !0, ~2
3 ASSIGN !0, ~3
4 4 ECHO !0
5 5 > RETURN 1
2个问题:
我不太会读操作码,所以也许我错过了一些东西,我猜测操作数〜2,3 vs !0,〜2 的顺序很重要,但我不知道怎么做。
最佳答案
此处的关键参与者是operator precedence,因此,尽管是表达式中的最后一个元素,但仍将$a++
评估为首先(即$a
之前)。请注意,post
中的post increment
表示该表达式(变量)的 Action 后评估,而整个表达式(代码行)的而不是评估。
在您的第一种情况下,代码是这样的:
$result = 3 * $a++;
因此用于乘法的
$a
的值为3
,因为它先被读取然后递增。该表达式中不再使用$a
,因此$a
的新值并不重要,除非再次引用$a
,否则它不会影响我们: $a = 3
$result = 3 * $a++
= 3 * 3
// $a is 4 now
= 9
第二种情况不同:
$result = $a * $a++;
因为我们有不止一个对
$a
的引用。评估将采用这种方式: $a = 3
$result = $a * $a++
= $a * 3 // value of `$a` is 4 after post-increment
// evaluation, and this affects us as we
// evaluate $a again
= 4 * 3
= 12
为了使答案更完整,让我们添加另一种情况:
$result = $a++ * $a++;
评估将类似地进行,最后使用不同的
$a
值: $a = 3
$result = $a++ * $a++
// $a is 4 now
= 3 * $a++
= 3 * 4
// $a is 5 now
= 12
一旦理解,这看起来就很清楚了,但另一方面,通过编写您认为知道其工作方式与实际工作方式的代码,它可以很好地展示出您可以多么聪明地超越自己:)因此,您要么需要仔细阅读语言文档,要么确保您知道,从而确定您编写的代码将执行什么操作,或者只是为了避免在以后的调试 session 中出于个人理智而编写过于“聪明”的代码:) KISS原则存在是有原因的。
关于php - 后增量表演很奇怪,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59880917/