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
则没有?)有谁知道一个有启发性的解释可以解决我对这两种类型的困惑?
最佳答案
Scala 中的优秀书籍 Programming 有一个不错的 explanation :
class Outer {
class Inner
}
在 Scala 中,内部类使用表达式
Outer#Inner
寻址。而不是 Java 的 Outer.Inner
. .
语法是为对象保留的。例如,假设您实例化了两个 Outer
类型的对象。 , 像这样:val o1 = new Outer
val o2 = new Outer
这里
o1.Inner
和 o2.Inner
是两种依赖路径的类型(它们是不同的类型)。这两种类型都符合(属于)更通用的类型 Outer#Inner
,它表示具有 Outer 类型的任意外部对象的 Inner 类。相比之下,输入 o1.Inner
指具有特定外部对象(从 o1
引用的对象)的内部类。同样,输入 o2.Inner
引用具有不同的特定外部对象(从 o2
引用的对象)的内部类。在 Scala 中,就像在 Java 中一样,内部类实例持有对封闭外部类实例的引用。例如,这允许内部类访问其外部类的成员。因此,您不能在不以某种方式指定外部类实例的情况下实例化内部类。一种方法是在外部类的主体内实例化内部类。在这种情况下,将使用当前的外部类实例(从 this 引用)。另一种方法是使用依赖于路径的类型。例如,因为类型 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
^
关于scala - 路径依赖类型是子类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5976791/