在Scala中,所有抽象类型在擦除后都具有相同的类型

时间:2017-01-12 15:48:35

标签: scala type-erasure

以下代码无法编译,因为两个乘法运算符在删除后具有相同的类型(f: Object)Object

我知道类型擦除,但我见过的所有情况都删除了<{strong>通用类型,如List[Int]List[String],如Scala double definition (2 methods have the same type erasure)中所述。

如何让Scala对待不同类型的XxxT`类型不同?

trait AbstractTypes {
  type ScalarT
  type VectorT
  abstract class Operators(u: VectorT) {
    def *(f: ScalarT): VectorT
    def *(v: VectorT): VectorT
  }
}

2 个答案:

答案 0 :(得分:6)

这是DummyImplicit的用途:

trait AbstractTypes {
  type ScalarT
  type VectorT
  abstract class Operators(u: VectorT) {
    def *(f: ScalarT): VectorT
    def *(v: VectorT)(implicit dummy1: DummyImplicit): VectorT
  }
}

如果您需要更多重载次数相同的话,您可以拥有任意数量的DummyImplicit

答案 1 :(得分:0)

使用answer中的一个技巧来处理链接的问题(将秒方法的参数声明为按名称调用):

trait AbstractTypes {
  type ScalarT
  type VectorT
  abstract class Operators(u: VectorT) {
    def *(f: ScalarT): VectorT
    def *(v: => VectorT): VectorT
  }
}

object ConcreteTypes extends AbstractTypes {
  type ScalarT = Double
  type VectorT = Seq[Double]
  class ConcreteOperators(u: Seq[Double]) extends Operators(u) {
    def *(f: Double): Seq[Double] = u.map(_ * f)
    def *(v: => Seq[Double]): Seq[Double] = 
      (u zip v).map { case (a, b) => a * b }
  }
}

new ConcreteTypes.ConcreteOperators(Seq(2.0, 3.0, 5.0)) * 7.0 
Seq[Double] = List(14.0, 21.0, 35.0)

new ConcreteTypes.ConcreteOperators(Seq(2.0, 3.0, 5.0)) * Seq(1.0, 2.0, 3.0) 
Seq[Double] = List(2.0, 6.0, 15.0)