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

3
以下代码无法编译,因为两个乘法运算符在类型擦除后具有相同的类型: (f: Object)Object 我了解类型擦除,但所有我见过的情况都是泛型类型被擦除了,例如Scala double definition (2 methods have the same type erasure)中回答的List[Int]List[String]
如何让Scala将不同类型的XxxT`类型视为不同类型?
trait AbstractTypes {
  type ScalarT
  type VectorT
  abstract class Operators(u: VectorT) {
    def *(f: ScalarT): VectorT
    def *(v: VectorT): VectorT
  }
}
2个回答

8
这就是DummyImplicit的作用:
trait AbstractTypes {
  type ScalarT
  type VectorT
  abstract class Operators(u: VectorT) {
    def *(f: ScalarT): VectorT
    def *(v: VectorT)(implicit dummy1: DummyImplicit): VectorT
  }
}

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


0

使用答案中的一个技巧来解决链接问题(将seconds方法的参数声明为按名称调用):

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)

有趣的技巧,但它会稍微改变语义。例如,当您使用函数而不是值时,每次使用都会再次调用该函数。 - Bébul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接