2012-05-12 36 views
5

Im czytanie tej strony http://www.scala-lang.org/node/137, rozumiem co kowariancji jest i dolne granice, jak również, ale to, co nie jest jasne, czy to linia:granice Scala niższy typ i kowariancji

Niestety, ten program nie kompiluje, ponieważ Adnotacja kowariancji jest możliwa tylko wtedy, gdy zmienna typu jest używana tylko w kowariantnych pozycjach . Ponieważ zmienna typu T pojawia się jako typ parametru metody przedawnienia, ta reguła jest zepsuta.

dlaczego elem musi być instancją supertypem z T, jeśli ListNode jest już kowariantna dlaczego elem nie może zostać dołączona do bieżącej listy.

+0

Wyjaśnienie jest dość proste. Zmienna typu T pojawia się jako typ parametru. To nie jest stanowisko kowariantne. Co dokładnie stanowi problem? –

Odpowiedz

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 

Wyobraźmy sobie następującą pozwolono:

// invalid code 
class Foo[+T] { 
    def bar(x: T) = println(x) 
} 

Od Foo jest kowariantna na T ta jest ważna (prosty uskok, ponieważ Foo[Sub] jest Foo[Super]):

val foo : Foo[Super] = new Foo[Sub] { 
    override def bar(x: Sub) = x.subMethod 
} 

Teraz foo jest, o ile nam wiadomo, Foo[Super] jak każdy inny, ale jego bar metoda nie zadziała, ponieważ realizacja bar wymaga Sub:

foo.bar(sup) // would cause error! 
+0

Ok, rozumiem, teraz z linii "ten program nie kompiluje" z witryny scala, nie oznacza to, że faktycznie naruszamy coś w tym konkretnym kodzie i nie podklaskujemy wyraźnie Foo [SomeClass], kompilator chroni przed potencjalnym błędem środowiska wykonawczego, czy jestem w błędzie? – loki

+0

Masz rację, ale to tak, jakby kompilator stosował jakąkolwiek inną regułę statycznego pisania, na przykład nie pozwalając ci wywoływać metod list na Ciągach. Jak pokazuje powyższe, logicznie niespójne byłoby uznanie argumentu metody za typ kowariantny, więc nie pozwala. –