1

私は Scala を学ぼうとしていて、「せっかちな人のための Scala」を読むことから始めようと思いました。そこで彼は、次のクラスを使用して構築順序の問題を挙げています。

class Animal {
  val range: Int = 10
  val env: Array[Int] = new Array[Int](range)

}

class Ant extends Animal {
  override val range: Int = 2
}

そして、なぜ がenv空の Array[Int] になるのかを説明し、初期の定義構文を含む、それを防ぐ方法の説明に進みます。

しかし...これを行うだけでそれを防ぐことはできません:

class Animal(val range: Int = 10) {
  val env: Array[Int] = new Array[Int](range)
  /* do animal stuff */
}

class Ant(override val range: Int = 2) extends Animal(range) {
     /* do ant stuff */
}

??? 初期の定義構文が本当に必要なのはなぜですか?

4

1 に答える 1

5

初期のインスタンス化の必要性を理解するためのより良い方法は、特性を混合することから来ると思います。トレイトを使用すると、この種の問題を回避するために微調整できるコンストラクターがなくなります。この非常に些細で完全に非現実的な例を考えてみましょう:

trait Foo{
  val bar:String
  val barLength = bar.length()
}

object MyFoo extends Foo{
  val bar = "test"
}

現時点では、このコードはNullPointerExceptionMyFoo が作成されたときにbarをスローしbar.length()ます。しかし、早期初期化を使用し、次のように再定義MyFooした場合:

object MyFoo extends {val bar = "test"} with Foo{

}

その後、すべてが正常に機能します。

于 2013-06-03T13:33:52.067 に答える