Scala的存在类型和Java的通配符在示例中的区别是什么?

31
比Stack Overflow问题 “什么是存在类型?”更具体,Scala的存在类型和Java的通配符有什么区别,最好有一些说明性的例子?
到目前为止,我看到的所有东西似乎都相当等效。
几个参考文献。Martin Odersky 提到了它们; Google的我的问题的热门搜索结果:

MO:原始的通配符设计…受存在类型启发。实际上,原始论文中对存在类型进行了编码。但是当Java的最终设计出现时,这种联系有点失落了。


在我看来,fotNelton似乎对其他人遗漏的一些相关补充内容做出了贡献,这更值得深入了解。让第二句话的后半部分更加清晰地解释会很有趣... - ib84
5个回答

15
这是Martin Odersky在Scala用户邮件列表上的回答:
原始的Java通配符类型(如Igarashi和Viroli在ECOOP论文中所述)确实只是对存在类型的简写。我被告知并且我在关于Wild FJ的FOOL'05论文中也读到了,最终版本的通配符类型与存在类型有一些微妙的差异。我不确定具体的差异是什么(它们的形式主义与经典的存在类型相去甚远,无法准确定位差异),但也许仔细阅读Wild FJ论文会有所启示。
因此,似乎Scala存在类型和Java通配符类型是等价的。

2
整个对话的链接将非常有用。 - HMM
除此之外,没有太多其他的东西。 - oxbow_lakes

7
以下是Martin Odersky对此的更详细解释(其余内容可以在这里找到):
Scala需要存在类型主要有三个方面。第一个是我们需要对Java的通配符进行一些解释,而存在类型就是我们对它们进行解释的方式。第二个是我们需要对Java的原始类型进行一些解释,因为它们仍然存在于库中,即未泛型化的类型。如果你得到了一个Java原始类型,比如java.util.List,那么这是一个你不知道元素类型的列表。这也可以用Scala的存在类型来表示。最后,我们需要存在类型作为一种解释在Scala高层次上发生的事情的方式。Scala使用与Java相同的泛型擦除模型,因此当程序运行时,我们不再看到类型参数。我们必须进行擦除,因为我们需要与Java进行交互。但是当我们进行反射或想表达在VM中发生的事情时,会发生什么?我们需要能够使用Scala中拥有的类型来表示JVM的操作,而存在类型让我们做到了这一点。它们让您谈论那些您不知道某些方面的类型。

7

它们应该是等效的,因为它们的主要目的是与Java的通配符交互。


我已经将Martin Odersky的评论添加到我的原始问题中。阅读他对Bill Venners的回应,感觉存在类型并不等同于通配符。当然,我相当确定我曾经读过一些东西,基本上吹嘘Scala 没有通配符类型(因为它最初没有),这是一件好事。 - oxbow_lakes
有人指出,Scala没有原始类型可能是夸大其词的事实。 - oxbow_lakes
@oxbow_lakes,List[_] 在 Scala 中被认为是原始列表吗? - Kevin Meredith

4

它们非常相似,但Scala的存在类型被认为更加强大。例如,Scala的存在类型可以是上下限制的,而Java的通配符只能是上限制的。

例如,在Scala中:

scala> def foo(x : List[_ >: Int]) = x
foo: (x: List[_ >: Int])List[Any]

foo接受一个参数列表,其下限为Int。


2
Java的通配符也支持下限。 public List<?> foo(List<? super Integer> lst) { return lst; } - ihji

1
< p > List[_] 表示法(正如其他答案所指出的是 Java 的 List[?] 更强大的类比)是 Scala 中存在类型更一般概念的退化情况。更一般的存在类型


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接