У меня есть процедура scala, создающая большую структуру данных с использованием еще большего индекса в процессе. Поскольку я хочу сделать это за один проход и не запутаться в сложном разрешении приоритета, я использую ленивые валы в результате, инициализированном выражениями, которые могут не иметь правильного значения (или вообще никакого) в момент создания компонента, но сделает это после завершения всего процесса сборки. Это означает, что каждый компонент конечного результата имеет синтетическую ссылку на замыкание со всем моим индексом, и потенциально, пока какой-либо из них все еще находится в памяти, мой индекс не может быть собран мусором. Очевидно, я этого не хочу - в идеале я хотел бы иметь возможность сделать второй проход по структуре, чтобы инициализировать значения, если это необходимо (и гарантировать, что любые ошибки будут обнаружены на этом этапе), и пусть индекс будет собранный мусор. В настоящее время я передаю выражение инициализации по имени через несколько функций и использую его в ленивом объявлении val, что эквивалентно этому:
class Component(init : =>Component) {
lazy val property = init
}
...
new Component(index.get(parameters))
Это звук? Будет ли синтетическое поле инициализации разыменовано после доступа к lazy val? Что, если я хочу использовать его в функции инициализации, например:
class Component(init : =>Component) {
private def evaluate = init
lazy val property = evaluate
}
Существуют ли какие-либо общие правила, которые следует учитывать при программировании с замыканиями?
index.get
уже является функцией, которая возвращаетComponent
, для чего нужна упаковка? Кроме того, какие типы являются изменяемыми (некоторые из них должны быть изменены, иначе нет проблем с порядком инициализации) - person Martijn   schedule 26.05.2015