scala - 路径依赖类型是子类型吗?

标签 scala subtype 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 
  }
}

我说得对吗A.this.B是路径依赖类型?! (这是我目前的理解)
上面的例子是否意味着类型 A.this.BA#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.Innero2.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/

相关文章:

scala - AWS Glue Spark 作业 - 使用 CatalogSource 时如何对 S3 输入文件进行分组?

scala - Scala为在JVM上运行做出了哪些妥协?

scala - 类标签和路径相关的类型,具有蛋糕图案的味道

scalaz.Equal 用于路径依赖类型

Scala 依赖类型无法编译

json - 使用 Scala 进行无噪音 JSON 处理

scala - 在 Scala 中使用 FoldRight 的 FoldLeft

mysql - 没有(标识)唯一属性的父类(super class)型表

java - Java 中的动态调度

SQL 设计、连接类型和子类型