2

给定一个特征T

trait T {
  def v: Int
  def +(t: T): T
}

下面的课A

case class A(v: Int) extends T {
  def +(a: A) = A(v + a.v)
}

不是 的有效子类型T。的实现A.+过于严格,因为它只接受 type 的元素,A而 的签名T.+要求所有实现都能够接受 type 的对象,T而不仅仅是 type 的对象A。到目前为止,很合理。

如果我想让 的实现具有T限制性,我可以修改 和 的声明,T如下A所示

trait T[This <: T[This]] {
  def v: Int
  def +(t: This): This
}

case class A(v: Int) extends T[A] {
  def +(a: A) = A(v + a.v)
}

这显然会破坏类型签名。

有没有另一种方法来声明的实现T只需要与它们自己类型的对象兼容?

第一次编辑回复Landei的回答如下

虽然自我类型确实缩短了当前签名,但它们不会缩短T出现的其他签名,例如

trait C[D <: T[D], S] { self: S =>
  def +(perm: D): S
  def matches(other: S): Boolean
}
4

2 回答 2

1

您可以使用自我类型:

trait T[S] {
  self:S => 
  def v: Int
  def +(t: S): S
}

case class A(v: Int) extends T[A] {
  def +(a: A) = A(v + a.v)
}
于 2010-12-14T11:55:35.340 回答
1

您可以使用类型成员来执行此操作。我不知道你到底要找什么牌子的“短”。有一些冗余,但另一方面,没有类型参数可以为您节省大量括号。

trait TT {
  type This <: TT
  def v: Int
  def +(t: This): This
}
case class AA(v: Int) extends TT {
  type This = AA
  def +(a: This) = AA(v + a.v)
}
于 2010-12-16T10:50:04.333 回答