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

nai*_*rbv 3 inheritance types scala 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
}
Run Code Online (Sandbox Code Playgroud)

这个问题有两个部分:

是否有其他方法可以做到这一点,其中 MyClass 中的返回类型可以只是“MyClass”,而不必指定“type T = MyClass”?基本上,我希望能够将此特征添加到一个类中,而不必真正让子类显着改变其实现或考虑类型系统......只返回其自身的成员,并让该特征接受任何内容,只要它在子类型上是协变的。这还有道理吗?

在 MyTrait 中,如果取消注释,getOne 方法将给出错误“类型不匹配:”found : MyTrait.this.type (withunderlying type MyTrait) required: MyTrait.this.T

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

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

dhg*_*dhg 6

这是你想要的吗?

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
}
Run Code Online (Sandbox Code Playgroud)

它摆脱了type T = MyClass(允许您只输入MyClass返回类型)并修复了getOne.