我在Scala中编写了一个矩阵类,我认为实现转置操作的最佳方法是返回一个所有操作“转置”的接口。因此,如果matrix.apply(i, j)
返回第(i,j)个元素,则matrix.transpose返回包含返回矩阵(j,i)的apply方法的接口(但不是数据的副本)。我写的那个界面就像这样(我真正写的东西比较麻烦):
abstract class Matrix {
def apply(i : Int, j : Int) : Double
//other matrixy operations
private def outer = this //so the inner can see the enclosing instance
object TransposedInterface extends Matrix {
def apply(i :Int, j : Int) = outer(j, i)
}
}
我觉得哪个很可爱,但是现在TransposedInterface
里面还有一个名为TransposedInterface
的对象,依此类推,递归,它在哪里结束?
我在翻译中尝试了以下内容:
class Outer(val i : Int) {
object Inner extends Outer(i + 1)
}
val o = new Outer(1)
o.Inner.Inner.Inner.Inner.i
我认为运行和评估为5,就像它应该的那样。
那究竟发生了什么?内部对象懒惰地评估了吗?当它没有立即被使用时,它是垃圾收集,然后下次再次实例化outer.Inner被调用?这是我没想过的伏都教吗?
答案 0 :(得分:3)
它被懒惰地实例化,并且在收集外部类之前不会被垃圾收集,因为外部类包含对它的引用。
通常,object Foo { ... }
的行为与lazy val Foo = { ... }
非常相似。由于对象在有效时不能为null,但肯定是对象,因此在此上下文中它们更有效(更快地检查存在 - 只是看到字段为空),但是缺点是需要第二个.class
文件。 (你通常不关心有多少个类文件,所以这可能不是什么大问题。)