试图从特征中找到更简单的方法来引用子类的类型

时间:2012-09-05 03:05:30

标签: scala inheritance types covariance

所以,这里有一个人为的例子:

trait MyTrait { 
  type T <: MyTrait
  val listOfT:List[T]
  def getFirst:T
  //def getOne:T = if( listOfT.length > 0 ) { getFirst } else { this }
}

class MyClass extends MyTrait {
  type T = MyClass
  override val listOfT:List[T] = List[MyClass](this)
  override def getFirst:T = listOfT.head
}

这个问题有两个部分:

还有其他方法可以做到这一点,MyClass中的返回类型可能只是“MyClass”而不必指定“type T = MyClass”吗?基本上我希望能够将这个特性添加到一个类中,而不必让子类显着改变它的实现,或者考虑类型系统......只返回它自己的成员,并且只要它具有特征接受任何东西在子类型上是协变的。这甚至有意义吗?

在MyTrait中,如果取消注释,getOne方法将给出错误“类型不匹配:”  发现:MyTrait.this.type(底层类型为MyTrait)  必需:MyTrait.this.T

如果我要将返回类型更改为this.type,我会得到相反的发现/必需类型不匹配。返回值实际上具有相同的类型(实际上是同一个对象)。

处理这类情况的正确方法是什么?

1 个答案:

答案 0 :(得分:4)

这是你想要的吗?

trait MyTrait[T <: MyTrait[T]] { self: T =>
  val listOfT: List[T]
  def getFirst: T
  def getOne: T = if (listOfT.length > 0) getFirst else self
}

class MyClass extends MyTrait[MyClass] {
  override val listOfT: List[MyClass] = List[MyClass](this)
  override def getFirst: MyClass = listOfT.head
}

它摆脱了type T = MyClass(允许你只将MyClass置于返回类型中)并修复了getOne定义中的编译错误。