2012-05-12 12 views
5

Im Lesen dieser Seite http://www.scala-lang.org/node/137, verstehe ich, was Kovarianz ist und die untere Grenze als gut, aber was nicht klar ist, ist diese Zeile:Scala untere Typ Grenzen und Kovarianz

Leider ist dieses Programm nicht kompilieren, weil Eine Kovarianz Annotation ist nur möglich, wenn die Typvariable nur in kovarianten Positionen verwendet wird. Da die Typvariable T als Parametertyp der Methode prepend erscheint, ist diese Regel gebrochen.

warum elem eine Instanz eines übergeordneten Typ von T sein muss, wenn ListNode bereits covariant Deshalb elem nicht auf die aktuelle Liste vorangestellt werden kann.

+0

Die Erklärung ist ziemlich einfach. Die Typvariable T erscheint als Parametertyp. Dies ist keine kovariante Position. Was genau stellt hier ein Problem dar? –

Antwort

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 

folgendes erlaubt wurden Imagine:

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

Da Foo auf T covariant ist, gilt dies (eine einfache upcast, da ein Foo[Sub] ist ein Foo[Super]):

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

Jetzt foo ist, soweit wir wissen, ein Foo[Super] wie jeder andere, aber sein bar Methode wird nicht funktionieren, weil die bar Implementierung eines Sub erfordert:

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

Ok, ich verstehe, jetzt aus der Zeile "dieses Programm kompiliert nicht" bilden die Scala-Site es, bedeutet nicht, dass wir tatsächlich etwas in diesem bestimmten Code verletzen und wir Foo [SomeClass] nicht explizit kompilieren schützt gerade gegen einen möglichen Laufzeitfehler, bin ich falsch? – loki

+0

Sie haben Recht, aber es ist genau so, wie wenn der Compiler eine andere Regel der statischen Typisierung anwendet, so als ob Sie die List-Methoden für Strings nicht aufrufen könnten. Wie das obige zeigt, wäre es logisch inkonsistent, das Argument einer Methode als kovarianten Typ zu definieren, so dass es Sie nicht erlaubt. –