Scala @specialized in template base的好处是调用时模板参数已知?
假设我有:Scala @specialized in template base的好处是调用时模板参数已知?,scala,generics,boxing,specialized-annotation,Scala,Generics,Boxing,Specialized Annotation,假设我有: trait Normalizer[T]{ def apply(x:T):T } case class DoubleNormalizer() extends Normalizer[Double] { def apply(x:Double):Double { ... impl ... } } 装箱/拆箱是否发生在以下任一情况下,@specialized是否会避免这种情况 val d1:Normalizer[Double] val d2:DoubleNormal
trait Normalizer[T]{
def apply(x:T):T
}
case class DoubleNormalizer() extends Normalizer[Double] {
def apply(x:Double):Double {
... impl ...
}
}
装箱/拆箱是否发生在以下任一情况下,@specialized是否会避免这种情况
val d1:Normalizer[Double]
val d2:DoubleNormalizer
d1(123.4) // boxes Double? (probably yes because d1.apply(T=Object)
d2(123.4) // boxes Double? maybe not because s2.apply(Double)
在没有专门化的情况下,对d2.apply的调用是否接收Double或Object
可行的:
- 前者因为编译器可以在编译时证明,所以apply方法的类型是double
- 后者是因为DoubleNormalizer.apply(Double)是Normalizer.apply(Object)的实现,而apply(Object)是JVM将提供的唯一具体类型签名
scalac-print Normalizer.scala
并检查类型擦除的输出。请参阅@Yawar谢谢。我理解专业化会如何影响这个方法对trait的调用。但是当类型被完全指定时,您引用的文章没有说明在子类中何时可能发生装箱/取消装箱。实际上,它可能是因为基类的方法规范是泛型的,也可能不必是泛型的,因为在调用编译器时可以证明只传递了原语double。是哪一个?我现在时间不多,但这篇文章实际上告诉您如何自己找到:scalac-print Normalizer.scala
并检查类型擦除的输出。