为什么scala值类#toString包含案例类信息?
可用于实现类型安全,无需拆箱 我的印象是,在运行时,这样的类型/类将“不存在”,被视为简单类型(例如,值类为什么scala值类#toString包含案例类信息?,scala,value-class,Scala,Value Class,可用于实现类型安全,无需拆箱 我的印象是,在运行时,这样的类型/类将“不存在”,被视为简单类型(例如,值类case类X(I:Int)扩展AnyVal在运行时将是简单的Int) 但如果在值类实例上调用.toString方法,它会打印如下内容: scala> val myValueClass = X(3) myValueClass: X = 3 scala> myValueClass.toString res5: String = X(3) 所以我猜编译器毕竟包含了一些信息 不太可能
case类X(I:Int)扩展AnyVal
在运行时将是简单的Int
)
但如果在值类实例上调用.toString
方法,它会打印如下内容:
scala> val myValueClass = X(3)
myValueClass: X = 3
scala> myValueClass.toString
res5: String = X(3)
所以我猜编译器毕竟包含了一些信息 不太可能。编译器创建一个静态方法(在Scala中,它对应于类的伴生对象),该方法以int值作为参数进行调用,以模拟对值类类型对象调用方法
值类本身只存在于源代码中。在编译的字节码中,使用实际的原语int并调用静态方法,而不是使用实际方法调用新的对象实例。您可以阅读有关此机制的更多信息。值类的设计应确保添加或删除
扩展AnyVal
(如果合法)不会改变计算结果(除非即使是非case值类也会像case类一样自动定义等于和hashCode
)。这要求在某些情况下它们能够生存,例如
def toString(x: Any) = x.toString
toString(myValueClass)
但你问题中的情况并不是其中之一
更精确地解释了值类是如何实现的,并且有助于了解它们在什么情况下仍然存在,尽管此后一些细节可能发生了变化