加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 如何避免使用路径依赖类型的糟糕类型转换?

发布时间:2020-12-16 18:15:43 所属栏目:安全 来源:网络整理
导读:我是 Scala的新手,不知道为什么我必须在下面的代码中对路径依赖类型做一个(不直观的)类型转换. (我不喜欢getter,setter或nulls,他们在这里分开操作并消除错误来源的歧义) // Module A public APIclass ModA { trait A}// Module B public API that depends o
我是 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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读