为什么 scala 值 class#toString 包含大小写 class 信息?

why scala value class#toString contains case class info?

value classes 可用于实现类型安全而无需拆箱开销。

我的印象是,在运行时,这样的 types/classes 会 "not exist",被视为简单类型(例如,值 class case class X(i: Int) extends AnyVal 将是一个简单的Int 在运行时)。

但是如果你确实在值 class 实例上调用了 .toString 方法,它会打印如下内容:

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

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

所以我猜编译器毕竟包含了一些信息?

不是真的。编译器创建一个静态方法(在 Scala 中,这对应于 class 的伴随对象),它以您的 int 值作为参数调用,以模拟对您的值 class 类型调用方法对象。

你的价值class本身只存在于源代码中。在编译后的字节码中,使用了一个实际的原始 int 并调用了静态方法,而不是使用真正的方法调用的新对象实例。您可以阅读有关此机制的更多信息 here.

值 类 的设计使得添加或删除 extends AnyVal(如果合法)不应更改计算结果(即使非大小写值 类 也具有 equalshashCode 像 case 类 一样自动定义)。这要求他们在某些情况下生存,例如

def toString(x: Any) = x.toString

toString(myValueClass)

但你问题中的情况不属于其中之一。

http://docs.scala-lang.org/sips/completed/value-classes.html#expansion-of-value-classes 更准确地解释了值 类 是如何实现的,并且有助于了解它们在哪些情况下存活下来,尽管此后一些细节可能发生了变化。