我有一个使用更大的索引在过程中创建大型数据结构的scala过程。因为我想要一次完成并且不会在复杂的优先解决方案中变得难以理解,所以在使用表达式初始化的结果中使用lazy vals,该表达式可能无法在创建时评估为正确值(或者任何其他值)该组件,但是一旦整个构建过程完成,就会这样做。这意味着最终结果的每个组成部分都有对整个索引的闭包的合成引用,并且可能只要它们中的任何一个仍在内存中,我的索引就不能被垃圾收集。很显然,我不想要它 - 理想情况下,我希望能够在结构上进行第二遍以便根据需要初始化值(并确保在此处捕获任何错误),并让索引为垃圾收集。目前,我通过名字初始化表达式通过几个功能和懒惰VAL声明中使用它,等价于:Scala:懒惰的vals,按名称调用,关闭和内存泄漏
class Component(init : =>Component) {
lazy val property = init
}
...
new Component(index.get(parameters))
是这种声音?将通过取消引用一次lazy val访问的合成init字段?如果我想在初始化函数中使用它,就像这样:
class Component(init : =>Component) {
private def evaluate = init
lazy val property = evaluate
}
有没有什么规则与封闭编程时保持在一般的想法?
你能稍微加重一点真实的代码吗?如果'index.get'已经是一个返回一个'Component'的函数,那么这个包的好处是什么?此外,哪些类型是可变的(有些必须是,否则没有初始化顺序问题) – Martijn
真正的代码是相当庞大的,但底层的问题是非常基本的:合成闭包垃圾收集后,懒惰的val初始化,如果它只用于该初始化(特殊情况),并有任何规则管理它(通用之一)。在我的情况下,唯一的可变结构是在构建过程中使用的索引,所有其他正向/循环引用都是通过用表达式返回正确值的表达式来初始化的惰性val解析的。闭包的存在是因为初始化表达式可能比较复杂,并且有关于哪些元素不应该关心的论点 – Turin
它不一定是真正的代码 - 甚至是任何真正的代码,只是足够自成一体编译并显示有问题的行为的例子 – Martijn