why scala value class#toString contains case class

2019-07-29 15:29发布

value classes can be used to achieve type safety without the overhead of unboxing.

I had the impression that in runtime such types/classes would "not exist", being seen as simple types (for instance, a value class case class X(i: Int) extends AnyVal would be a simple Int on runtime).

But if you do call a .toString method on a value class instance it would print something like:

scala> val myValueClass = X(3)
myValueClass: X = 3

scala> myValueClass.toString
res5: String = X(3)

so I guess the compiler includes some information after all?

2条回答
Anthone
2楼-- · 2019-07-29 16:05

Value classes are designed so that adding or removing extends AnyVal (if legal) shouldn't change the results of calculations (except even non-case value classes have equals and hashCode defined automatically like case classes). This requires that in some circumstances they survive, e.g.

def toString(x: Any) = x.toString

toString(myValueClass)

but the situation in your question isn't one of them.

http://docs.scala-lang.org/sips/completed/value-classes.html#expansion-of-value-classes explains more precisely how value classes are implemented and is useful to see in what cases they survive, though some details may have changed since.

查看更多
来,给爷笑一个
3楼-- · 2019-07-29 16:07

Not really. The compiler creates a static method (in Scala this corresponds to the class's companion object) which is called with your int value as a parameter in order to simulate calling a method on your value class-typed object.

Your value class itself only exists in the source code. In compiled bytecode an actual primitive int is used and static methods are called rather than new object instances with real method calls. You can read more about this mechanism here.

查看更多
登录 后发表回答