我有一些功能:
def f(x: Int) = x * x然后我称之为:
var y = 0
f { y += 1; y }为上述代码生成的字节码如下所示:
0: iconst_0
1: istore_1
2: aload_0
3: iload_1
4: iconst_1
5: iadd
6: istore_1
7: iload_1
8: invokevirtual #18 // Method f:(I)I
11: pop
12: return如果我更改函数def (x: Int)来表示逐名调用:
def f(x: => Int) = x * x为同一部分代码生成的字节码如下所示:
0: new #24 // class scala/runtime/IntRef
3: dup
4: iconst_0
5: invokespecial #28 // Method scala/runtime/IntRef."<init>":(I)V
8: astore_1
9: aload_0
....我的问题是:
这是一条规则,对名字调用,我们对引用开放,还是它取决于语义分析阶段的编译?
发布于 2014-04-18 15:28:25
名为形式参数的实际参数总是打包成所谓的"thunk“(术语可以追溯到20世纪60年代的Algol ),这样就可以对包含实际参数的表达式进行零、一个或多个(任意数目)的计算。如果这个表达式有副作用的话,关于多个评估的一点是很重要的。
“引用”的具体用法与以下事实有关:在被调用的函数中执行的代码将对调用方法中的局部变量(字面上,特别是var)产生副作用。这就是为什么IntRef参与进来的原因。在这种情况下,将始终使用某种类型的"ref“(取决于实际参数表达式中引用的var的类型)。如果不涉及var,则将该值简单地复制到thunk。
https://stackoverflow.com/questions/23155590
复制相似问题