即時閱讀此頁http://www.scala-lang.org/node/137,我明白協方差下限爲好,但它目前還不清楚是這一行:斯卡拉低型邊界和協方差
不幸的是,這個程序不能編譯,因爲只有在類型變量僅在 協變位置中使用時,纔可以使用協方差 註釋。由於類型變量T顯示爲方法前置的參數類型 ,因此此規則被破壞。
爲什麼elem
必須的T
超類的一個實例,如果ListNode
已經是協變的,爲什麼elem
無法預先考慮到當前列表。
即時閱讀此頁http://www.scala-lang.org/node/137,我明白協方差下限爲好,但它目前還不清楚是這一行:斯卡拉低型邊界和協方差
不幸的是,這個程序不能編譯,因爲只有在類型變量僅在 協變位置中使用時,纔可以使用協方差 註釋。由於類型變量T顯示爲方法前置的參數類型 ,因此此規則被破壞。
爲什麼elem
必須的T
超類的一個實例,如果ListNode
已經是協變的,爲什麼elem
無法預先考慮到當前列表。
class Super {override def toString = "Super"}
class Sub extends Super {override def toString = "Sub"; def subMethod {} }
val sup = new Super
val sub = new Sub
設想以下被允許:
// invalid code
class Foo[+T] {
def bar(x: T) = println(x)
}
由於Foo
是T
協變,這是有效的(一個簡單的向上轉型,由於Foo[Sub]
爲Foo[Super]
):
val foo : Foo[Super] = new Foo[Sub] {
override def bar(x: Sub) = x.subMethod
}
就我們所知,現在foo
就像其他任何Foo[Super]
一樣,但它的bar
方法是行不通的,因爲bar
實施需要Sub
:
foo.bar(sup) // would cause error!
好吧,我明白了,現在從'這個程序不編譯'這一行,它並不意味着我們實際上違反了這個特定代碼中的某些東西,而且我們也沒有顯式地繼承Foo [SomeClass],編譯器只是防止潛在的運行時錯誤,我錯了嗎? – loki
你是對的,但它就像編譯器應用任何其他靜態類型的規則,比如不讓你在字符串上調用List方法。如上所示,允許一個方法的參數是一個協變類型在邏輯上是不一致的,所以它不會讓你。 –
的解釋是非常簡單的。類型變量T顯示爲參數類型。這不是一個協變的立場。究竟是什麼造成了問題? –