5
我是新來的斯卡拉,不知道爲什麼我必須做一個(直覺對我來說)在下面的代碼中與路徑依賴類型相關的類型轉換。 (我不喜歡的getter,setter方法也沒有空,他們來這裏是爲了獨立的操作和歧義錯誤的根源)如何避免使用路徑依賴類型的可怕類型轉換?
// 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
}
}
我看了一下單類型通知編譯器,當兩個類型相同,但我不知道如何在這裏應用。 在此先感謝。
非常感謝回答特拉維斯,但你的解決方案僅適用內類範圍,在方法範圍內(就像我最初暴露的例子),它不起作用。 行:'val modBImpl = new ModBImpl(modAImpl);' 以前編譯,現在抱怨:類型不匹配;找到:ModAmpl required:M forSome {type M <:ModA {type A = this.A}} 和行'b.set(a)'現在抱怨:type mismatch;找到:modAImpl.A required:this.A –
在這種情況下('val modBImpl = new ModBImpl [modAImpl.A](modAmpl)'),您可以明確提供類型參數。這不是令人滿意的,但它的工作原理,它比鑄造更好。 –
對不起特拉維斯,但你剛剛寫的代碼行不能編譯。 儘管如此,請假設特質ModA有很多成員,而不僅僅是A.我需要ModB上可用的ModA的所有成員。 –