Pet*_*itz 3 scala path-dependent-type
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
}
}
Run Code Online (Sandbox Code Playgroud)
我是对的,这A.this.B是一种路径依赖型?!(这是我到目前为止的理解)上面的例子是否意味着类型A.this.B 是一个子类型 A#B?(如果是的话,我猜不同的是,一个实例A.this.B有一个A对比实例的引用A#B没有?)有没有人知道一个有启发性的解释来解决我对这两种类型的困惑?
kas*_*ens 15
优秀的Scala编程书有一个很好的解释:
class Outer {
class Inner
}
Run Code Online (Sandbox Code Playgroud)
在Scala中,使用表达式Outer#Inner而不是Java 来解决内部类Outer.Inner.该.语法保留给对象.例如,假设您实例化两个类型的对象Outer,如下所示:
val o1 = new Outer
val o2 = new Outer
Run Code Online (Sandbox Code Playgroud)
这里o1.Inner和o2.Inner两个路径依赖类型(它们是不同的类型).这两种类型都符合(是子类型)更通用的类型Outer#Inner,它表示具有Outer类型的任意外部对象的Inner类.相比之下,type o1.Inner指的是具有特定外部对象(引用自的对象)的Inner类o1.同样,type o2.Inner指的是具有不同的特定外部对象(引用自的对象)的Inner类o2.
在Scala中,与Java一样,内部类实例包含对封闭外部类实例的引用.例如,这允许内部类访问其外部类的成员.因此,如果不以某种方式指定外部类实例,则无法实例化内部类.一种方法是在外部类的实体内实例化内部类.在这种情况下,将使用当前外部类实例(从中引用).另一种方法是使用路径依赖类型.例如,因为类型o1.Inner命名特定的外部对象,所以可以实例化它:
scala> new o1.Inner
res1: o1.Inner = Outer$Inner@13727f
Run Code Online (Sandbox Code Playgroud)
生成的内部对象将包含对其外部对象的引用,该引用的对象o1.相比之下,因为类型Outer#Inner没有命名任何特定实例Outer,所以无法创建它的实例:
scala> new Outer#Inner
<console>:6: error: Outer is not a legal prefix for
a constructor
new Outer#Inner
^
Run Code Online (Sandbox Code Playgroud)
简而言之:是的
如果需要,可以考虑A#B对包含A(因此不能直接构造,如同任何抽象类型)具有抽象引用,此引用在路径依赖子类中具体化.