2016-04-06 9 views
0

Ja! Ein weiterer dieser Frage, und ja, ich lese bereits viele dieser Fragen in stackoverflow und verstehe immer noch nicht dieses Konzept und seine Anwendung.Scala Co und Contravarianz

Also, ich bin ich Newcomer zu Scala, und wie viele Leute habe ich immer noch nicht das Konzept der Contravariance, ich lese die Programmierung Scala, 2. Auflage, und auf Seite 283 beginnt die Erklärung von co und Kontra mit folgendem Beispiel:

gibt die Hierarchie:

class CSuper { def msuper() = println("CSuper") } 
class C extends CSuper { def m() = println("C") } 
class CSub extends C { def msub() = println("CSub") } 

dann gibt es eine Funktion und einige Anwendungsbeispiele:

var f: C => C = (c: C) => new C 
    f   = (c: CSuper) => new CSub 
    f   = (c: CSuper) => new C 
    f   = (c: C) => new CSub 
    f   = (c: CSub) => new CSuper // COMPILATION ERROR! 

in Java-Denken Ich weiß, dass der letzte Ausdruck nicht kompiliert wird, da CSuper ein Supertyp von CSub ist.

Was ich nicht verstehe, ist, was bedeutet, dass ein Typ, in diesem Fall die Funktion1 [-C, + C], im ersten Parameter kontravariant ist?

Das Buch sagt, dass für Kontra ist, wenn where X[String] is a supertype of X[Any], for some type X.

Die co/Kontra nur appliable in den Unterklassen der parametrisierte Typen ist, meine ich, da wir eine Function1 verwenden, die Varianz zu Subtypen von Function1 gilt nur, wäre es das?

Und wie funktioniert es eigentlich, und wann sollte/brauche ich es?

+0

"ich habe schon viele dieser Fragen im Stackoverflow gelesen und verstehe immer noch nicht ..." - es gibt nicht wirklich nützliche Hinweise in Ihrer Frage, was wir möglicherweise schreiben könnten, das wäre nicht das Gleiche Sachen, die du schon gelesen hast.Sie haben hier einige Fragen gestellt, die alle sehr weit gefasst sind und alle Duplikate enthalten. –

+0

@SethTisue, yeah, ich denke, die Fragen, die ich bereits gelesen habe, haben das Wissen, das ich suche, aber die Art, wie sie beantwortet werden, lässt mich nicht verstehen, ich hoffte, dass jemand das vielleicht auf eine andere Art erklären könnte. –

+0

@KennedyOliveira Suchen Sie nach dem Liskow-Substitutionsprinzip. – pedrofurla

Antwort

2

Wenn T 'eine Unterklasse von T ist, wird Container [T'] als Unterklasse von Container [T] betrachtet?

[+T]kovarianten: C [T '] ist eine Unterklasse von C [T],
[-T]kontra: C [T] ist eine Unterklasse von C [T']

Function1 ist definiert als trait Function1[-T1, +R], daher sind die Parameter kontravariant und der Ergebnistyp ist kovariant.

Das bedeutet, dass Funktionen, die Argumente sind geordneten Typen Argumentations Art der gegebenen Funktion, und die Ergebnistyp Subtyp Ergebnistyp gegebene Funktion ist selbst Subtyp der gegebenen Funktion.

In Ihrem Beispiel, wenn Sie verschiedene Funktionsdeklarationen f vom Typ C => C zuweisen, wird nur die Zuweisung von gültigen Subtypen kompilieren.

nämlich nur diese Funktionsdeklarationen gelten Subtypen von C => C:

var f: C => C = (c: C) => new C 
f   = (c: C) => new C 
f   = (c: C) => new CSub 
f   = (c: CSuper) => new C 
f   = (c: CSuper) => new CSub 

Alles andere ist entweder übergeordneter Typ von C => C und kann nicht auf f oder nicht verwandten Typ zugeordnet werden.