比 Stack Overflow 问题更具体一点什么是存在类型?,Scala的存在类型和Java的通配符有什么区别,最好有一些说明性的例子?
到目前为止,在我所看到的所有内容中,它们似乎都相当。
一些参考。Martin Odersky提到了他们;谷歌对我的问题的热门回答:
MO:最初的通配符设计……受到存在类型的启发。事实上,原始论文有一个存在类型的编码。但是当实际的最终设计出现在 Java 中时,这种联系有点丢失了
比 Stack Overflow 问题更具体一点什么是存在类型?,Scala的存在类型和Java的通配符有什么区别,最好有一些说明性的例子?
到目前为止,在我所看到的所有内容中,它们似乎都相当。
一些参考。Martin Odersky提到了他们;谷歌对我的问题的热门回答:
MO:最初的通配符设计……受到存在类型的启发。事实上,原始论文有一个存在类型的编码。但是当实际的最终设计出现在 Java 中时,这种联系有点丢失了
这是 Martin Odersky 在 Scala 用户邮件列表中的回答:
最初的 Java 通配符类型(如 Igarashi 和 Viroli 在 ECOOP 论文中所描述的)确实只是存在类型的简写。我被告知并且我在 FOOL '05 关于 Wild FJ 的论文中读到通配符的最终版本与存在类型有一些细微的差别。我不知道究竟是什么意思(他们的形式主义与经典存在主义类型相差太远,无法确定差异),但仔细阅读 Wild FJ 论文可能会对此有所了解。
所以看起来 Scala 存在类型和 Java 通配符是等价的
它们应该是等价的,因为它们的主要目的是与 Java 的通配符交互。
Martin Odersky 提供了一个更详细的答案(其余的可以在这里找到):
Scala 需要存在类型来处理三件事。首先是我们需要理解 Java 的通配符,而存在类型就是我们对它们的理解。第二个是我们需要对 Java 的原始类型有所了解,因为它们仍然在库中,即未生成的类型。如果你得到一个 Java 原始类型,例如 java.util.List,它是一个你不知道元素类型的列表。这也可以在 Scala 中通过存在类型来表示。最后,我们需要存在类型来解释 Scala 高级别的 VM 中发生的事情。Scala 使用泛型的擦除模型,就像 Java 一样,所以当程序运行时我们不再看到类型参数。我们必须进行擦除,因为我们需要与 Java 进行互操作。但是,当我们进行反思或想要表达 VM 中发生的事情时会发生什么?我们需要能够使用 Scala 中的类型来表示 JVM 所做的事情,而存在类型让我们能够做到这一点。他们让您谈论您不了解这些类型的某些方面的类型。
它们非常相似,但 Scala 的存在类型应该更强大。例如,Scala 的存在类型既可以是上限也可以是下限,而 Java 的通配符只能是上限。
例如,在 Scala 中:
scala> def foo(x : List[_ >: Int]) = x
foo: (x: List[_ >: Int])List[Any]
foo 采用具有 Int 下限的参数列表。
The List[_]
notation (which as other answers point out is a more powerful analog to Java's List[?]
) is a degenerate case of the more general notion of an existential type in Scala.