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 と評価されるかは、当然のことだと思います。

では、実際には何が起こっているのでしょうか。内部オブジェクトは遅延評価されますか? すぐに使用されていないときにガベージ コレクションを実行し、次に outer.Inner が呼び出されたときに再度インスタンス化しますか? 私が思いもよらなかったのはブードゥー教ですか?

4

1 に答える 1

3

これは遅延インスタンス化され、外部クラスへの参照が含まれているため、外部クラスが収集されるまでガベージコレクションされません。

一般に、object Foo { ... }のように動作しlazy val Foo = { ... }ます。オブジェクトは有効な場合はnullにできませんが、確かにオブジェクトであるため、このコンテキストではより効率的です(存在のチェックが高速です。フィールドがnullかどうかを確認するだけです)が、2番目の.classファイルが必要になるという欠点があります。(通常、クラスファイルの数は気にしないので、これはおそらく大したことではありません。)

于 2012-07-23T19:36:46.910 に答える