为什么scala值类#toString包含case类信息?

时间:2016-11-28 11:47:00

标签: scala value-class

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

我的印象是,在运行时这样的类型/类将“不存在”,被视为简单类型(例如,值类case class X(i: Int) extends AnyVal在运行时将是一个简单的Int

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

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

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

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

2 个答案:

答案 0 :(得分:4)

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

您的值类本身仅存在于源代码中。在编译的字节码中,使用实际的原语int,并且使用实际方法调用调用静态方法而不是新的对象实例。您可以阅读有关此机制的更多信息here

答案 1 :(得分:1)

设计了值类,以便添加或删除extends AnyVal(如果合法)不应更改计算结果(除非非案例值类别具有equals和{{1}像case类一样自动定义)。这要求在某些情况下它们能够存活,例如

hashCode

但问题中的情况不是其中之一。

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