5

我在 Scala 中编写了一个矩阵类,我认为实现转置操作的最佳方法是只返回一个包含所有“转置”操作的接口。因此,如果matrix.apply(i, j)返回第 (i, j) 个元素,则 matrix.transpose 返回一个接口(但不是数据的副本),其中包含一个返回 matrix(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。

那么究竟发生了什么?内部对象是否懒惰地评估?不立即使用时是否会进行垃圾收集,然后在下次调用 external.Inner 时再次实例化?是我没想到的巫毒吗?

4

1 回答 1

3

它是惰性实例化的,并且在收集外部类之前不会被垃圾收集,因为外部类包含对它的引用。

一般来说,object Foo { ... }行为非常像lazy val Foo = { ... }. 由于对象在有效时不能为空,但肯定是对象,因此在这种情况下它们更有效(更快地检查是否存在——只查看字段是否为空),但存在需要第二个.class文件的缺点。(你通常不关心有多少类文件,所以这可能没什么大不了的。)

于 2012-07-23T19:36:46.910 回答