2012-05-12 38 views
5

即時閱讀此頁http://www.scala-lang.org/node/137,我明白協方差下限爲好,但它目前還不清楚是這一行:斯卡拉低型邊界和協方差

不幸的是,這個程序不能編譯,因爲只有在類型變量僅在 協變位置中使用時,纔可以使用協方差 註釋。由於類型變量T顯示爲方法前置的參數類型 ,因此此規則被破壞。

爲什麼elem必須的T超類的一個實例,如果ListNode已經是協變的,爲什麼elem無法預先考慮到當前列表。

+0

的解釋是非常簡單的。類型變量T顯示爲參數類型。這不是一個協變的立場。究竟是什麼造成了問題? –

回答

2
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) 
} 

由於FooT協變,這是有效的(一個簡單的向上轉型,由於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! 
+0

好吧,我明白了,現在從'這個程序不編譯'這一行,它並不意味着我們實際上違反了這個特定代碼中的某些東西,而且我們也沒有顯式地繼承Foo [SomeClass],編譯器只是防止潛在的運行時錯誤,我錯了嗎? – loki

+0

你是對的,但它就像編譯器應用任何其他靜態類型的規則,比如不讓你在字符串上調用List方法。如上所示,允許一個方法的參數是一個協變類型在邏輯上是不一致的,所以它不會讓你。 –