0

我想编写具有通用的、可能很慢的类型参数化方法实现的代码,该方法适用于实现某个接口的所有类,但如果子类愿意,仍然允许使用更有效的实现来专门化此方法。

但是,下面的代码不太好用

class A(val i:Int)

class B {
    def f[T](t:T) = println(t.toString)
}

class C extends B { 
    override def f[A](a:A) = println(a.i * a.i) 
}

因为它将 C 类中的 A 视为类型参数,而不是在类型参数仅为 A 的情况下覆盖函数的东西。

有没有办法在运行时不使用 match 来编写我想要的代码?

4

1 回答 1

0

你要做的是:

scala> class A(val i: Int)
defined class A

scala> class B { 
     |   def f[T](t: T) = println(t.toString)
     | }
defined class B

scala> class C extends B { 
     |   override def f[T <: A](a: T) = println(a.i * a.i) 
     | }
<console>:10: error: overriding method f in class B of type [T](t: T)Unit;
 method f has incompatible type
         override def f[T <: A](a: T) = println(a.i * a.i) 

但正如类型系统告诉你的那样,这是错误的。您在这里违反了Liskov 替换原则

相反,您可以做的是创建T类级别类型参数或抽象类型成员。然后您可以将其约束在子类中,如下所示:

scala> class B {
     |   type T
     |   def f(t: T) = println(t.toString)
     | }
defined class B

scala> class C extends B {
     |   type T = A
     |   override def f(a: T) = println(a.i * a.i)
     | }
defined class C

scala> (new C).f(new A(11))
121

您没有提供更多信息,所以我不知道这是否适用于您的特定情况。

编辑:

这是一种特殊化事物的方法:使用类型类。代码:(结果比预期的要复杂。)

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class A(i: Int)

case object B

trait F[-A] {
  def f(a: A): Unit
}

trait FLowPriorityImplicits {
  implicit object FAny extends F[Any] {
    def f(a: Any) = println(a.toString)
  }
}

trait FImplicits extends FLowPriorityImplicits {
  implicit object FA extends F[A] {
    def f(a: A) = println(a.i * a.i)
  }
}

object F extends FImplicits

def f[A](x: A)(implicit f: F[A]) = f.f(x)

// Exiting paste mode, now interpreting.

defined class A
defined module B
defined trait F
defined trait FLowPriorityImplicits
defined trait FImplicits
defined module F
f: [A](x: A)(implicit f: F[A])Unit

scala> f(B)
B

scala> f(A(2))
4
于 2012-10-28T10:49:37.827 回答