如何在Scala中限制重写方法中的类型?

Gre*_*reg 5 functional-programming scala

trait Rendered
trait TemplateRendered extends Rendered
trait Media {
  def send[T <: Rendered](cooked:T)
}
case class EmailMedia() extends Media {
  override def send(cooked:TemplateRendered) {}  // compile error this line
}
Run Code Online (Sandbox Code Playgroud)

我想要一个带有send()方法的Media模板,该方法接受子类Rendered对象.在具体的类(EmailMedia)中,我想将其锁定到Rendered的特定子类,或者在这种情况下是TemplateRendered.(即使类中的类型比特征中的类型更具限制性/特异性)

我怎样才能做到这一点?

编译器不喜欢这里的尝试.试过这个:

case class EmailMedia() extends Media {
  override def send[T <: TemplateRendered](cooked:T) {}
}
Run Code Online (Sandbox Code Playgroud)

fal*_*epl 8

怎么样:

trait Rendered
trait TemplateRendered extends Rendered

trait Media[T <: Rendered] {
  def send(cooked: T): Unit
}

case class EmailMedia() extends Media[TemplateRendered] {
  override def send(cooked: TemplateRendered): Unit = {}
}
Run Code Online (Sandbox Code Playgroud)

您希望Media提供多种通用方法吗?如果是这种情况,您可以考虑将该泛型参数移动到类型成员以使事情更具可读性:

trait Rendered
trait TemplateRendered extends Rendered
trait BazzRendered extends Rendered

trait Media {
  type SendRend <: Rendered
  type FooRend <: Rendered

  def send(cooked: SendRend): Unit
  def foo(bar: FooRend): Unit
}

case class EmailMedia() extends Media {
  type SendRend = TemplateRendered
  type FooRend = BazzRendered

  override def send(cooked: SendRend): Unit = {}
  override def foo(bar: FooRend): Unit = {}
}
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一下,这被称为F绑定多态.+1 (2认同)