trait A {
trait B {
def foo: A.this.B = new B{}
def bar: A#B = foo
def baz: A.this.B = bar // type mismatch; found : A#B required: A.this.B
}
}
我说得对吗A.this.B
是路径依赖类型?! (这是我目前的理解)
上面的例子是否意味着类型A.this.B
是一个子类型 A#B
? (如果是的话,我想区别在于A.this.B
引用了实例A
相比A#B
哪一个不是?)
有谁知道一个有启发性的解释来解决我对这两种类型的困惑?
优秀的书《Programming in Scala》有相当不错的内容解释:
class Outer {
class Inner
}
在 Scala 中,内部类使用表达式来寻址Outer#Inner
而不是Java的Outer.Inner
. The .
语法是为对象保留的。例如,假设您实例化了两个类型的对象Outer
, 像这样:
val o1 = new Outer
val o2 = new Outer
Here o1.Inner
and o2.Inner
是两种路径依赖类型(并且它们是不同的类型)。这两种类型都符合更通用的类型(是其子类型)Outer#Inner
,它表示具有 Outer 类型的任意外部对象的内部类。相比之下,输入o1.Inner
指具有特定外部对象的内部类(从o1
)。同样,输入o2.Inner
指的是具有不同的、特定的外部对象的内部类(从o2
).
在 Scala 中,与在 Java 中一样,内部类实例保存对封闭外部类实例的引用。例如,这允许内部类访问其外部类的成员。因此,如果不以某种方式指定外部类实例,就无法实例化内部类。一种方法是在外部类的主体内实例化内部类。在这种情况下,将使用当前的外部类实例(从此引用)。另一种方法是使用路径相关类型。例如,因为类型 o1.Inner 命名了一个特定的外部对象,所以您可以实例化它:
scala> new o1.Inner
res1: o1.Inner = Outer$Inner@13727f
生成的内部对象将包含对其外部对象的引用,该对象引用自o1
。相比之下,因为类型Outer#Inner
没有指定任何具体实例Outer
,您无法创建它的实例:
scala> new Outer#Inner
<console>:6: error: Outer is not a legal prefix for
a constructor
new Outer#Inner
^
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)