路径依赖和内部类

时间:2019-01-08 16:54:24

标签: scala dependent-type path-dependent-type

以下示例代码无法编译,并显示以下错误。

class Outer {
  class Inner

  val instance: Inner = new Inner

  def verify(pd: Inner): Boolean = pd == instance
}

class UseOuter(val pdp: Outer) {
  def foo: pdp.Inner = pdp.instance
}

class UseCase {
  val pdp = new Outer
  val user = new UseOuter(pdp)

  val i = user.foo

  pdp.verify(i)
}

错误:

test.sc:19: type mismatch;
 found   : UseCase.this.user.pdp.Inner
 required: UseCase.this.pdp.Inner
  pdp.verify(i)
             ^
Compilation Failed

我不确定,但是读Inner Classes表示这是预期的行为吗?具体来说,下面的句子:

  

与此类内部类是成员的类Java语言相反   封闭类的内部,在Scala中,此类内部类绑定到了   外物。

如果是这种情况,而这确实是所需的行为,是否可以在Scala中编码此要求?

有一些类似的问题,但它们都与内部类型有关,与类无关,因此建议的解决方案将不适用。

2 个答案:

答案 0 :(得分:2)

例如,您可以使用type projections

class Outer {
  class Inner

  val instance: Inner = new Inner

//  def verify(pd: Inner): Boolean = pd == instance
  def verify(pd: Outer#Inner): Boolean = pd == instance
}

class UseOuter(val pdp: Outer) {
//  def foo: pdp.Inner = pdp.instance
  def foo: Outer#Inner = pdp.instance
}

class UseCase {
  val pdp: Outer = new Outer
  val user: UseOuter = new UseOuter(pdp)

//  val i: user.pdp.Inner = user.foo
  val i: Outer#Inner = user.foo

  pdp.verify(i)
}

答案 1 :(得分:2)

这是一种在需要的时候维护依赖于路径的类型的安全性的方法。首先,修改UseOuter以将pdp的类型作为类型参数:

class UseOuter[O <: Outer](val pdp: O) {
  def foo: pdp.Inner = pdp.instance
}

然后,当实例化UseOuter时,明确地传递pdp.type作为类型参数:

val user = new UseOuter[pdp.type](pdp)

这使编译器可以记住pdp中的UseOuterpdp中的UseCase是相同的,因此类型正确匹配。