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):
Компилятор Scala переупорядочивает вещи в таких случаях, чтобы захваченный параметр находился в куче вместо стека и, таким образом, мог пережить вызов метода, который его создал. Эта перестановка все позаботится автоматически, поэтому вам не нужно беспокоиться об этом.
Может ли кто-нибудь объяснить, как это работает на уровне байтового кода? Является ли доступ похожим на переменную-член класса со всеми связанными с ней последствиями синхронизации и производительности?