Ich bin neu bei Scala und weiß nicht, warum ich eine (nicht intuitive für mich) Typumwandlung in Bezug auf pfadabhängige Typen im folgenden Code machen muss. (Ich mag nicht Getter, Setter noch nulls, sie sind hier, um getrennte Vorgänge und die Fehlerquelle disambiguate)Wie vermeidet man schreckliche Typumwandlungen mit pfadabhängigen Typen?
// Module A public API
class ModA {
trait A
}
// Module B public API that depends on types defined in Module A
class ModB(val modA: ModA) {
trait B {
def getA: modA.A;
def setA(anA: modA.A);
}
}
// One implementation of Module A
class ModAImpl extends ModA {
class AImpl extends A
}
// One implementation of Module B
class ModBImpl(mod: ModA) extends ModB(mod) {
class BImpl extends B {
private[this] var privA: modA.A = _;
override def getA = privA;
override def setA(anA: modA.A) = privA = anA;
}
}
object Main {
def main(args: Array[String]): Unit = {
// wiring the modules
val modAImpl = new ModAImpl;
val modBImpl = new ModBImpl(modAImpl);
// wiring objects
val a = new modAImpl.AImpl;
val b = new modBImpl.BImpl;
b.setA(a); //don't compile and complain: type mismatch; found: modAImpl.A required: modBImpl.modA.A
//i have to do this horrible and coutnerintuitive cast to workaround it
b.setA(a.asInstanceOf[modBImpl.modA.A]);
var someA: modAImpl.A = null;
someA = b.getA; // don't compile with same reason
someA = b.getA.asInstanceOf[modAImpl.A]; // horrible cast to workaround
println(a == b.getA); // however this prints true
println(a eq b.getA); // this prints true too
}
}
Ich habe über Singleton Typen lesen Sie den Compiler zu informieren, wenn zwei Typen gleich sind, aber ich weiß nicht, wie ich das hier anwenden soll. Vielen Dank im Voraus.
Sehr Dank für Travis zu beantworten, aber Ihre Lösung funktioniert nur innerhalb Der Klassenbereich innerhalb eines Methodenbereichs (wie im Beispiel, das ich ursprünglich angegeben hatte) funktioniert nicht. Die Zeile: 'val modBImpl = new ModBImpl (modAImpl);' die zuvor kompiliert wurden, klagt jetzt mit: type mismatch; gefunden: ModAImpl benötigt: M forSome {Typ M <: ModA {Typ A = this.A}} und die Zeile 'b.set (a)' klagt jetzt mit: type mismatch; found: modAImpl.A erforderlich: this.A –
In diesem Fall können Sie den Typparameter explizit angeben ('val modBImpl = new ModBImpl [modAImpl.A] (modAImpl)'). Was nicht befriedigend ist, aber es funktioniert, und es ist besser als Casting. –
Sorry Travis, aber die Codezeile, die du gerade geschrieben hast, kompiliert nicht. Trotzdem, bitte gehen Sie davon aus, dass das Merkmal ModA viele Mitglieder hat, nicht nur A. Ich brauche alle Mitglieder von ModA, die auf ModB verfügbar sind. –