首页 文章

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

提问于
浏览
2

以下代码无法编译,因为两个乘法运算符 have same type after erasure(f: Object)Object

我知道类型擦除,但我看到的所有情况都删除了 generic 类型,如 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

    这就是DummyImplicit的用途:

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

    如果需要更多重载次数相同的重载,则可以包含任意数量的 DummyImplicit .

  • 6

    使用answer中的一个技巧来处理链接的问题(将seconds方法的参数声明为call-by-name):

    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)
    

相关问题