Der folgende Codeabschnitt wird nicht kompiliert:
%Vor%Es gibt den folgenden Kompilierungsfehler zurück:
%Vor%Der folgende Code entspricht jedoch genau:
%Vor%Ich habe hier zwei Fragen:
Ich erwarte, dass das erste Stück Code kompiliert wird. Warum nicht?
Wenn es einen guten Grund gibt, warum der erste Code nicht kompiliert wird, würde ich erwarten, dass der zweite nicht kompiliert, aus dem gleichen Grund. Wie wird es dann erfolgreich kompiliert?
Ist einer dieser Fehler ein Fehler?
Ich weiß nicht, warum der Compiler die beiden Teile des Codes unterscheidet. Grundsätzlich wird der Code nicht kompiliert, da der von find
zurückgegebene Typ und der von fill
erwartete Typ nicht unbedingt gleich F
sein müssen, zumindest wenn find
und fill
für zwei aufgerufen wurden verschiedene Objekte.
Sie könnten den ersten Teil des zu kompilierenden Codes erstellen:
%Vor%Und du könntest den zweiten Teil des Codes nicht kompilieren mit:
%Vor%Dies sollte eher ein Kommentar als eine Antwort sein, aber ich habe noch keinen Ruf.
Um zu verstehen, was passiert, schauen wir uns einfachere Versionen von TestA.test
und TestB.test
an.
Beachten Sie, dass sich der Typ des Zwischenwerts s
auf String
bezieht, während der Typ des Zwischenwerts r
dies nicht tut.
Wenn wir die Existenziale einwerfen, erhalten wir einen Zwischenwert s
, dessen Typ äquivalent zu Any
ist und der somit keine gültige Eingabe für a.fill
ist. Der Zwischentyp für r
ist jedoch immer noch b.R
und daher immer noch eine geeignete Eingabe für b.fill
. Der Grund dafür ist, dass% ce_de% immer noch% ist, weil b.R
sich nicht auf b.R
bezieht, und entsprechend die Vereinfachungsregeln für existentielle Typen , F
entspricht b.R forSome {type F}
, genauso wie b.R
äquivalent zu Int forSome {type F}
.
Ist einer dieser Fehler ein Fehler?
Nun, es gibt irgendwo einen Fehler (ab scalac 2.11.7), weil der folgende Typ keine Überprüfung enthält.
%Vor% Ich irre mich also zu denken, dass Int
sich nicht auf b.R
bezieht, in diesem Fall ist F
nicht gleichbedeutend mit b.R forSome {type F}
und deine b.R
sollte keine Überprüfung geben, tut es aber, oder TestB.test
ist gleichbedeutend mit b.R forSome {type F}
, in diesem Fall sollte mein b.R
eine Überprüfung schreiben, tut es aber nicht.
Ich bin davon überzeugt, dass der Fehler bei Letzteren liegt, denn der Fehler tritt sogar auf, wenn die existenzielle Quantifizierung nichts mit TestB.test3
zu tun hat, wie im folgenden Beispiel.
Tags und Links scala existential-type type-inference type-members