具有泛型自我类型的Scala特征

njthzxwz  于 2022-11-09  发布在  Scala
关注(0)|答案(4)|浏览(152)

我有一个定义操作的特征,它是.Copy()的美化版本。它看起来像这样:

trait Optimize[T] {
    def optimize: T
}

以及一系列扩展它的类,如下所示:

case class Account(field: String) extends Optimize[Account] {
    def optimize = this.copy(field = field.intern())
}

有没有一种方法可以定义一个特征,它要求优化方法返回与self相同的类型,但在扩展它时不需要指定类型?这样我就能写下:

case class Account(field: String) extends Optimize {
    def optimize = this.copy(field = field.intern())
}
pvcm50d1

pvcm50d11#

您可以使用this.type作为返回值来引用实现者的类型。

def optimize: this.type = ???
ev7lccsx

ev7lccsx2#

简短的回答是:你不能。
您需要以某种方式(抽象类型)告诉Optimize该函数的返回类型是什么。
为什么?因为Optimize可以在不指定具体类的情况下在类型表达式中使用,并且编译器无法知道它将生成什么类型:

def someOtherMethod (a: Optimize) {
  val result = a.optimize // what is the type?
}

(对于抽象类型,返回类型为a.TOptimize#T...不是很有用)

gev0vcfq

gev0vcfq3#

如果您只想在扩展时避免指定类型参数,则可以将定义移动到类型成员,如下所示。

trait Optimize {
    type T
    def optimize: T
}

case class Account(field: String) extends Optimize {
    type T = Account
    def optimize = this.copy(field = field.intern())
}

但你只是把它从一个地方搬到了另一个地方。此外,使用类型参数对特征进行参数化要比让类型成员参与要好得多。
这样做的原因是什么?因为您的用例看起来非常适合类型参数。需要告诉特征优化()通过类型参数或类型成员返回的是什么。

kkih6yb8

kkih6yb84#

像这样的吗?

trait Ret[T]

trait A {
  def func(): Ret[_ <: A]
}

case class B() extends A {
  override def func(): Ret[B] = ???
}

相关问题