簡體   English   中英

Scala 特征返回子類型?

[英]Scala Trait Returning a Sub-type?

給定一個特征:

@ trait Foo {
    def withStuffAdded(str: String): Foo
  } 
defined trait Foo

然后我定義了Foo的一個子類:

@ class X(val str: String) extends Foo { 
    override def withStuffAdded(s: String): Foo = new X(str + s)
  } 
defined class X

最后,我嘗試定義這個 function:

@ def something(x: X): X = x.withStuffAdded("something") 
cmd3.sc:1: type mismatch;
 found   : ammonite.$sess.cmd1.Foo
 required: ammonite.$sess.cmd2.X
def something(x: X): X = x.withStuffAdded("something")
                                         ^
Compilation Failed

編譯器失敗,因為它期望返回Foo而不是X

如何更改Foo#withStuffAdded的定義以進行編譯,即在類型簽名中返回Foo的子類型?

路易斯的評論是完全正確的。 我將嘗試解釋如何找到評論中提到的解決方案。

如果我做對了,您實際上有興趣將子類作為子類方法中的結果類型,但是由於您的特征定義不允許這樣做,因此您被迫在方法withStuffAdded的 class X中返回一個Foo

雖然不明顯,但這聽起來像是一種代碼味道。 也許抽象類型是您開始尋找的東西,以放松設計並滿足您的要求:

trait Foo {
  type T <: Foo

  def withStuffAdded(str: String): T
}

class X(val str: String) extends Foo {
  type T = X

  override def withStuffAdded(s: String): X = new X(str + s)
}

現在這將起作用:

def something(x: X): X = x.withStuffAdded("something")

盡管設計靈活,但從這里開始,為了進一步改進它,可能的解決方案包括使用 f-bounded 多態性或類型類。

我可能會傾向於使用類型類,因為這是功能性的方式。 您需要什么取決於您的要求,但兩者都可以。

暫無
暫無

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

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