gpt4 book ai didi

scala - 如何避免使用路径依赖类型的可怕类型转换?

转载 作者:行者123 更新时间:2023-12-04 18:46:27 25 4
gpt4 key购买 nike

我是 Scala 的新手,不知道为什么我必须在以下代码中进行与路径相关类型相关的(对我来说不直观)类型转换。
(我不喜欢 getter、setter 或 nulls,它们在这里是为了分离操作并消除错误来源的歧义)

// 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
}
}

我已阅读有关单例类型以在两种类型相同时通知编译器的信息,但我不知道如何在此处应用。
提前致谢。

最佳答案

您可以在 ModB 上粘贴类型参数类型:

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
}
}

并且类型推断都按需要进行:
scala> val modAImpl = new ModAImpl
modAImpl: ModAImpl = ModAImpl@7139edf6

scala> val modBImpl = new ModBImpl(modAImpl)
modBImpl: ModBImpl[modAImpl.A] = ModBImpl@1dd7b098

scala> val a = new modAImpl.AImpl
a: modAImpl.AImpl = ModAImpl$AImpl@4cbde97a

scala> val b = new modBImpl.BImpl
b: modBImpl.BImpl = ModBImpl$BImpl@63dfafd6

scala> b.setA(a)

关于scala - 如何避免使用路径依赖类型的可怕类型转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13327399/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com