In the specification of value classes, it says:
A value class can only extend universal traits and cannot be extended itself. A universal trait is a trait that extends
Any
, only hasdef
s as members, and does no initialization. Universal traits allow basic inheritance of methods for value classes, but they incur the overhead of allocation. For example
trait Printable extends Any {
def print(): Unit = println(this)
}
class Wrapper(val underlying: Int) extends AnyVal with Printable
val w = new Wrapper(3)
w.print() // actually requires instantiating a Wrapper instance
First Question
Now, I would take this to mean that the following (probably) does not require instantiation:
trait Marker extends Any
class Wrapper(val underlying: Int) extends AnyVal with Marker {
def print(): Unit = println(this) //unrelated to Marker
}
val w = new Wrapper(3)
w.print() //probably no instantiation as print is unrelated to Marker
Am I correct?
Second Question
And I would think there is an even chance as to whether this requires instantiation or not:
trait Printable extends Any {
def print(): Unit //no implementation
}
class Wrapper(val underlying: Int) extends AnyVal with Printable {
override def print() = println(this) //moved impl to value class
}
val w = new Wrapper(3)
w.print() // possibly requires instantiation
On the balance of probability, I would also think that no instantiation would be needed - am I correct?
Edit
I'd not thought about the exact implementation of print()
in the example:
def print(): Unit = println(this)
Let's say that I used the following instead:
def print(): Unit = println(underlying)
Would these cause instantiations?
print(this)
. Presumably had I chosenprintln(underlying)
no instantiation would have been necessary? – Holytide