我想编写具有类型参数化方法的通用的,可能很慢的实现的代码,该方法适用于实现某个接口的所有类,但仍允许子类根据需要使用更高效的实现来专门化此方法。 / p>
但是,以下代码不能正常工作
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的情况下覆盖函数。
有没有办法编写我想要的代码而不在运行时使用匹配?
答案 0 :(得分: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 substitution principle。
您可以做的是使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