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 のスタック フレームのメモリ アドレスを表すため、非常に印象的です。「Programming in Scala」のクロージャーの章を読んだところですが、その点について次のことしか述べていません (p. 155):
このような場合、Scala コンパイラーは、キャプチャーされたパラメーターがスタックではなくヒープ上に存在するように再配置します。この再配置はすべて自動的に処理されるため、心配する必要はありません。
これがバイトコードレベルでどのように機能するかを詳しく説明できる人はいますか? アクセスは、関連するすべての同期とパフォーマンスへの影響を伴うクラスのメンバー変数に似ていますか?