我有一个程序,它使用一组元素的堆栈。这里的上下文并不重要。该代码包含以下说明:
val last = current_stack.pop
current_stack.peek.addAll(last)
在某些时候,我将它们分解如下:
current_stack.peek.addAll(current_stack.pop)
令我惊讶的是,该程序的行为有所不同。
有人对这种行为差异有解释吗?
看起来 xtend 只是编译为 Java,所以假设这个翻译相对简单(并且不会重新排序表达式的部分),让我们看一下等效的 Java:
vav last = current_stack.pop()
current_stack.peek().addAll(last)
// vs
current_stack.peek().addAll(current_stack.pop())
java 规范通常说,除了括号和运算符优先级之外,事物的操作方式是从左到右。具体来说,对于方法调用,第 15.12.4 节说:
在运行时,方法调用需要五个步骤。首先,可以计算目标参考。其次,对参数表达式进行求值。 …
这里,目标引用是来自
current_stack.peek()
的对象。根据 Java 规范,它会在参数表达式之前求值,特别是在第二个示例中,它会在 current_stack.pop()
之前求值。
(我链接了 Java 8 JLS,因为它是 Google 中首先出现的内容,但这不是他们在修订之间会更改的内容。)