相关疑难解决方法(0)

Scala中的闭包内存管理如何工作?

Scala允许关闭

def newCounter = {
  var a=0
  () => {a+=1;a}
}
Run Code Online (Sandbox Code Playgroud)

它定义了在每次调用返回一个新的独立的反函数开始一个函数1:

scala> val counter1 = newCounter
counter1: () => Int = <function0>

scala> counter1()
res0: Int = 1

scala> counter1()
res1: Int = 2

scala> val counter2 = newCounter
counter2: () => Int = <function0>

scala> counter2()
res2: Int = 1

scala> counter1()
res3: Int = 3
Run Code Online (Sandbox Code Playgroud)

这是非常令人印象深刻的,因为通常a会在newCounter的堆栈帧上代表内存地址.我刚刚阅读了"Scala编程"的封闭章节,并且在此事上只有以下内容(第155页):

Scala编译器在这种情况下重新排列事物,以便捕获的参数在堆上而不是堆栈中存在,因此可以比创建它的方法调用更长.这种重新安排都是自动完成的,因此您不必担心.

任何人都可以详细说明它如何在字节码级别上工作?访问是否类似于具有所有相关同步和性能影响的类的成员变量?

closures memory-management scala

16
推荐指数
1
解决办法
790
查看次数

与Java内部类相比,Scala闭包 - >最终VS var

我首先问过这个关于final在Java 中使用匿名内部类的问题: 为什么我们使用带有匿名内部类的final关键字?

我实际上正在阅读马丁奥德斯基的Scala书.似乎Scala简化了很多Java代码,但对于Scala闭包,我注意到了一个显着的差异.

在Java中,我们使用匿名内部类"模拟"闭包,捕获最终变量(将被复制到堆上而不是堆栈中),在Scala中我们可以创建一个可以捕获val的闭包,但是也是一个var,因此在闭包调用中更新它!

所以我们可以使用没有final关键字的Java匿名内部类!我还没读完这本书,但是现在我没有找到关于这种语言设计选择的足够信息.

谁能告诉我,为什么马丁Odersky的,谁似乎真的照顾功能的副作用,选择关闭,以便能够同时捕捉valvar,而不是唯一的val

Java和Scala实现的优点和缺点是什么?

谢谢

相关问题: 使用Scala闭包,何时捕获的变量开始存在于JVM堆上?

java closures scala anonymous-function inner-classes

7
推荐指数
1
解决办法
1225
查看次数