簡體   English   中英

Scala 具有通用自身類型的特征

[英]Scala trait with generic self type

我有一個特征,它定義了一個動作,它是 .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())
}

簡答:你做不到。

需要告訴的一種或另一種方式(抽象類型) Optimize該函數的返回類型。

為什么? 因為Optimize可以在類型表達式中使用而不指定具體類,並且編譯器無法知道它將生成什么類型​​:

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

(在抽象類型的情況下,返回類型將是aTOptimize#T aT ...不是很有用)

如果你想要的是避免在擴展時指定一個類型參數,你可以將定義移動到這樣的類型成員。

trait Optimize {
    type T
    def optimize: T
}

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

但是你只是將它從一個地方移到另一個地方。 此外,使用類型參數參數化特征比獲取涉及的類型成員要好得多。

這樣做的原因是什么? 因為您的用例似乎是類型參數的完全有效的情況。 需要通過type參數或類型成員告訴特性optimize()返回什么。

您可以使用this.type作為返回值來引用實現者的類型。

def optimize: this.type = ???

像這樣的東西?

trait Ret[T]

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM