[英]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.