以下示例代码无法编译,并显示以下错误。
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中编码此要求?
有一些类似的问题,但它们都与内部类型有关,与类无关,因此建议的解决方案将不适用。
答案 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
中的UseOuter
与pdp
中的UseCase
是相同的,因此类型正确匹配。