Domanda

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.

È stato utile?

Soluzione

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.

Altri suggerimenti

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top