Ответ 1
Анонимная функция (и фактически любая функция) в scala на самом деле является объектом (экземпляр Function*
). Когда он создается, захват vals выполняется путем копирования vals во внутренние поля функционального объекта. В теле функции (то есть в методе object object apply
) доступ к захваченным vals осуществляется путем доступа к этим полям.
Захват варов аналогичен, за исключением того, что компилятор должен добавить уровень косвенности: доступ к значению var осуществляется через некоторый скрытый изменяемый держатель (просто объект с изменяемым полем, указывающим на текущее значение var) и это этот держатель, который копируется в объект функции. При записи в var (либо локальным кодом, либо объектом функции) это поле владельца. Этот механизм гарантирует, что локальный код и функциональный код обрабатывают одни и те же данные, и оба видят друг друга.
Таким образом, ответ заключается в том, что захваченные vals и захваченный var оба всегда живут в куче (будь то непосредственно как поле объекта функции или как поле некоторого объекта-обертки)