Scala'da yeniyim ve aşağıdaki kodda yola bağımlı türlerle ilgili neden bir (benim için anlamadığım) tür dökümünü yapmam gerektiğini bilmiyorum. ,Yol bağımlı türlerle çalışan korkunç tipte dökümler nasıl önlenir?
// 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
}
}
Ben iki tip aynı olduğunda derleyici bilgilendirmek için tekil türleri hakkında okudum (onlar ayrı operasyonlarda için buradayız ve hataların kaynağını belirsizliği, alıcılar, ayarlayıcılar ne de boş değerlere sevmiyorum) ama bunu nasıl uygulayacağımı bilmiyorum. Şimdiden teşekkürler.
class ModA { trait A }
class ModB[AA](val modA: ModA { type A = AA }) {
trait B {
def getA: AA
def setA(anA: AA)
}
}
class ModAImpl extends ModA { class AImpl extends A }
class ModBImpl[AA](
mod: ModA { type A = AA }) extends ModB(mod) {
class BImpl extends B {
private[this] var privA: AA = _
override def getA = privA
override def setA(anA: AA) = privA = anA
}
}
Ve tür kesmesi tüm istediğiniz gibi çalışır:
Çok teşekkür ancak çözüm yalnızca içinde çalışır sınıf kapsamı, bir yöntem kapsamı içinde (aslında maruz kaldığım örnek gibi) işe yaramıyor. satırı: 'val modBImpl = yeni ModBImpl (modAImpl);' daha önce derleme, şimdi ile şikayet: tür uyuşmazlığı; Bulunan: ModAImpl gerekli: M forSome {type M <: ModA {tip A = this.A}} ve 'b.set (a)' satırı şu şekilde davranır: tür uyuşmazlığı; found: modAImpl.A required: this.A –
Bu durumda, açık olarak type parametresini sağlayabilirsiniz ('val modBImpl = new ModBImpl [modAImpl.A] (modAImpl)'). Hangi tatmin edici değil, ama işe yarıyor ve dökümden daha iyidir. –
Üzgünüm Travis, ama yazdığınız kod satırı derlemiyor. Buna rağmen, lütfen ModA'nın sadece A değil çok sayıda üyesi olduğunu varsayalım. ModB'deki tüm ModA üyelerine ihtiyacım var. –