Question

I'd like to define a val in a trait that gets computed once by sub-class that gets instantiated.

For instance :

trait Example
{
    val p : Int
    val after : Int = p + 1
}

class Ex(x : Int) extends Example
{
    val p = x
}

I want after to be computed for each instance of Ex, but no matter which parameter x I give, after is always 1. As if, p was 0 for the computation.

Of course, it works with def, but then it is no longer computed only once.

Was it helpful?

Solution

after in Example is instantiated right away, before your Ex actually is instantiated - and then before even looking at your x.

To fix it you can turn after into a lazy val, it will be evaluated the first time you use it.

OTHER TIPS

First of all a val variable is immutable, so it can only be assigned once. So it would not be possible to do p = x. But when you do val p = x in the Ex class you are assigning other variable that you just defined, so after would not change.

You have to define the abstract variable var p in your Ex class, so it will be able to set the val p defined in Example. For example, define the var p in the constructor as below.

trait Example
{
    val p : Int
    val after : Int = p + 1
}

class Ex(val p : Int) extends Example

Demo

scala> val ex = new Ex(5)
ex: Ex = Ex@1f7ebc89

scala> ex.p
res4: Int = 5

scala> ex.after
res5: Int = 6
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top