Question

The following code throws IllegalArgumentException:

trait T{
  val x: Long
  require(x > 0)
}

object T extends App{
  val y = new T{ val x = 42L }
}

while the following does not:

trait T{
  def x(): Long
  require(x() > 0)
}

object T extends App{
  val y = new T{ def x() = 42L }
}

Why is that? When is require() called? Why is the val even defined at that point?

Was it helpful?

Solution

Because def declares a method, which is put in the class by the compiler, so it exists as soon as it is compiled. In order to return something, a method has to run through to the point at which it actually returns something, so there is no problem in your second example.

val declares an "immutable value", although it still has to be initialised, before which point it holds the default value for its type - in this case, 0. This initialisation takes place after the constructor of trait T runs, unless you change your example to use early initialization:

val y = new { val x = 42L } with T
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top