3
簡單的例子來說明該問題:爲什麼scala未能對f-綁定多態性進行類型推斷?
trait WTF[W <: WTF[W]] {
def get : Int
}
trait Zero extends WTF[Zero] {
override def get : Int = 0
}
case object Zero extends Zero
final case class Box(inner : Int) extends WTF[Box] {
override def get : Int = inner
}
def printWTF[W <: WTF[W]](w : W) = println(w.get)
printWTF(Box(-1))
printWTF(Zero)
Box
是好的,但Zero
產生錯誤:
WTF.scala:22: error: inferred type arguments [Zero.type] do not conform to method printWTF's type parameter bounds [W <: WTF[W]]
printWTF(Zero)
^
WTF.scala:22: error: type mismatch;
found : Zero.type
required: W
printWTF(Zero)
^
two errors found
如果我手動註釋的類型,它編譯:
printWTF[Zero](Zero)
printWTF(Zero : Zero)
第一線路按預期工作。我經常遇到無法從參數中推斷出類型參數的情況。例如def test[A](x : Int) : Unit
。 A
類型在參數簽名中無處顯示,因此應該手動指定它。
但是後者對我來說很模糊。我只是添加了總是爲真的類型轉換,奇蹟般地編譯器學習如何推斷方法類型參數。但Zero
始終是Zero
類型,爲什麼編譯器無法從我的提示中推斷出它?
>案例對象零的類型爲Zero.type和是WTF的子類型[0] 但是一般規則是你可以用任何子類替換任何類入口。第二行示例完全一樣。它不會更改類型簽名。 – ayvango
我不認爲任何人都知道Scala中完整的類型推斷規則。我所知道的是,它不會在您的示例中重試所有超類型的'Zero.type',並且您必須像我一樣使用一些額外的參數來幫助它。如果你的意思是你可以用'Zero.type'替換'WTF [Zero]中的'Zero',那麼你錯了,因爲'WTF'中的'W'是不變的。 –
我並不是說'WTF [Zero]裏面的'Zero'可以替代。但任何地方,凡是預期的'Zero'參數都可以用'Zero.type'替代,因爲函數調用允許這樣做,'Function [Zero,T]'是Function [Zero.type,T]的子類型' – ayvango