Ich habe folgende Klasse:
%Vor%Und der Compiler klagen:
%Vor%Ich habe viel nach dem Fehler gesucht, konnte aber nichts Nützliches finden hilf mir den Fehler zu verstehen.
Könnte jemand bitte erklären, warum der Fehler auftritt?
Die Fehlermeldung ist wirklich sehr klar, sobald Sie es verstehen. Lass uns zusammen kommen.
Sie deklarieren die Klasse Box
als Kovariante in ihrem Typparameter A
. Dies bedeutet, dass für jeden Typ X
extinguing A
(d. H.% Co_de%), X <: A
als Box[X]
betrachtet werden kann.
Um ein klares Beispiel zu geben, betrachten wir den Box[A]
-Typ:
Wenn Sie Animal
und Dog <: Animal
definieren, können sowohl Cat <: Animal
als auch Box[Dog]
als Box[Cat]
betrachtet werden, und Sie können z. Erstellen Sie eine einzelne Sammlung, die beide Typen enthält, und bewahren Sie den Typ Box[Animal]
auf.
Obwohl diese Eigenschaft in einigen Fällen sehr nützlich sein kann, werden auch die Operationen eingeschränkt, die Sie für Box[Animal]
bereitstellen können. Aus diesem Grund können Sie im Compiler Box
nicht definieren.
Wenn Sie die Definition von
erlauben %Vor%dann ist der folgende Code gültig:
%Vor% Die letzte Zeile ist offensichtlich ein Problem, weil def set
jetzt ein catBox
enthält! Die Argumente einer Methode erscheinen in der sogenannten kontravarianten Position, die das Gegenteil der Kovarianz ist. Wenn Sie Dog
definieren, dann bedeutet Box[-A]
Cat <: Animal
( Box[Cat] >: Box[Animal]
ist ein Supertyp von Box[Cat]
). Für unser Beispiel ist das natürlich unsensibel.
Eine Lösung für Ihr Problem besteht darin, die Box[Animal]
-Klasse unveränderlich zu machen (dh keine Möglichkeit zu geben, den Inhalt von Box
zu ändern) und stattdessen die in Ihrem Box
-Begleiter definierte apply-Methode zu erstellen neue Boxen. Wenn Sie möchten, können Sie case class
auch lokal definieren und nicht irgendwo außerhalb von set
angeben, indem Sie es als Box
deklarieren. Der Compiler wird dies erlauben, weil private[this]
garantiert, dass die letzte Zeile unseres fehlerhaften Beispiels nicht kompiliert wird, da die Methode private[this]
außerhalb einer bestimmten Instanz von set
vollständig unsichtbar ist.
Andere haben bereits eine Antwort gegeben, warum der Code nicht kompiliert wird, aber sie haben keine Lösung für die Kompilierung des Codes angegeben:
%Vor% Das Typargument B >: A
ist eine untere Grenze, die den Compiler anweist, bei Bedarf einen Supertyp abzuleiten. Wie im Beispiel zu sehen ist, wird Animal
abgeleitet, wenn Cat
angegeben wird.
Versuchen Sie zu verstehen, was es für Ihre Box[+A]
bedeutet, in A
:
Dies bedeutet, dass ein Box[Dog]
auch ein Box[Animal]
sein sollte, also sollte jede Instanz von Box[Dog]
alle Methoden haben, die ein Box[Animal]
hat.
Insbesondere sollte eine Box[Dog]
eine Methode
Es hat jedoch nur eine Methode
%Vor% Nun könntest du denken, dass du die erste von der zweiten ableiten kannst, aber das ist nicht der Fall: Ich möchte eine Cat
mit nur der zweiten Signatur einkisten? Das ist nicht machbar, und das sagt Ihnen der Compiler: Ein Parameter in einer Methode ist eine kontravariante Position (Sie können nur kontravariante (oder invariante) Typparameter eingeben).
Im Grunde können Sie A
s nicht setzen, wenn A
kovariant ist, Sie können es nur herausnehmen (zB: A
zurückgeben). Wenn Sie A
s eingeben möchten, müssen Sie contravariant
angeben.
Möchten Sie beides tun, dann machen Sie es einfach invariant
%Vor%Das Beste ist, es kovariant zu halten und den Setter loszuwerden und einen unveränderlichen Ansatz zu wählen.
Tags und Links scala