gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 14:55:38 28 4
gpt4 key购买 nike

Scala 允许闭包

def newCounter = {
var a=0
() => {a+=1;a}
}

它定义了一个函数,该函数在每次调用时返回一个新的独立计数器函数,起始于 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

这与往常一样令人印象深刻 a将代表 newCounter 堆栈帧上的内存地址。我刚刚阅读了“在 Scala 中编程”的闭幕章节,它只有以下几点要说(第 155 页):

The Scala compiler rearranges things in cases like this so that the captured parameter lives out on the heap, instead of the stack, and thus can outlive the method call that created it. This rearrangement is all taken care of automatically, so you don't have to worry about it.



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

最佳答案

您可以使用 scalac -Xprint:lambdalift <scala-file-name>调查此事。

你的代码实际上是这样的:

def newCounter = {
val a: runtime.IntRef = new runtime.IntRef(0);
new Function0 {
private[this] val a$1 = a
def apply() = {
a$1.elem = a$1.elem + 1
a$1.elem
}
}
}

任何 var 都有一个包装器由 lambda 使用。其他 vars (未在闭包中使用)是常见的语言环境变量。

此包装器的链接作为字段存储在函数实例中。
lambdalift-Xprint:lambdaliftcompiler phase .您可以通过 -Xshow-phases 获得所有阶段.您可以使用阶段编号而不是名称,当您不确定需要哪个阶段时,它会很有用。

关于scala - Scala 中闭包的内存管理是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17134246/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com