Sono nuovo di Scala e non so perché devo fare un cast di tipo (non intuitivo per me) relativo ai tipi dipendenti dal percorso nel seguente codice. (non mi piace getter, setter né nulli, sono qui per operazioni separate e disambiguare la fonte di errori)Come evitare tipi casuali di lavoro che funzionano con tipi dipendenti dal percorso?
// 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
}
}
Ho letto sui tipi di Singleton a informare il compilatore quando due tipi sono gli stessi, ma non so come applicarlo qui. Grazie in anticipo.
Molto grazie per la risposta Travis, ma la soluzione funziona solo all'interno l'ambito della classe, all'interno di un ambito del metodo (come nell'esempio che avevo originariamente esposto) non funziona. la riga: 'val modBImpl = new ModBImpl (modAImpl);' che in precedenza compila, ora si lamenta con: tipo mancata corrispondenza; trovato: ModAImpl richiesto: M forSome {tipo M <: ModA {tipo A = this.A}} e la riga 'b.set (a)' ora si lamenta con: tipo mancata corrispondenza; trovato: modAImpl.A richiesto: this.A –
In questo caso è possibile fornire esplicitamente il parametro type ('val modBImpl = new ModBImpl [modAImpl.A] (modAImpl)'). Il che non è soddisfacente, ma funziona, ed è meglio del casting. –
Scusa Travis, ma la riga di codice appena scritta non viene compilata. Nonostante ciò, si supponga che il tratto ModA abbia molti membri, non solo A. Ho bisogno di tutti i membri di ModA disponibili su ModB. –