25

那么例如为什么List(1,2,3,4).contains("wtf")还要编译呢?如果编译器拒绝这个不是很好吗?

4

3 回答 3

23

很多有趣的答案,但这是我自己的理论:如果contains没有收到Any,则Seq不能是协变的。

例如,请参阅 ,Set它不是协变的,并且contains采用 anA而不是Any

其原因留给读者作为练习。;-) 但这里有一个提示:

scala> class Container[+A](elements: A*) {                         
     |   def contains(what: A): Boolean = elements exists (what ==)
     | }
<console>:7: error: covariant type A occurs in contravariant position in type A of value what
         def contains(what: A): Boolean = elements exists (what ==)
                      ^
于 2010-09-09T18:12:50.363 回答
4

“包含”基本上是关于相等性测试,Scala 中的相等性(如在它之前的 Java 中)是无类型的。具有无类型相等的实用价值很小,但不为零。例如,在某些情况下,不同类的两个对象彼此相等是有意义的。例如,如果 RGBColor 类型的对象定义相同的色调,您可能希望它们与 PantoneColor 相等,或者如果它们包含相同的元素,则不可变的 HashSet 和不可变的 TreeSet 相等。也就是说,无类型平等也引起了很多麻烦,编译器可以很容易地捕捉到这一点List(1,2,3,4).contains("wtf")是荒谬的,但不会是其中之一。

大多数 Java 错误查找工具都包含用于检测不可能的非类型化相等使用的测试。(我在 IntelliJ IDEA 中编写了检查来执行此操作。)毫无疑问,当 Scala 错误查找工具上线时,这些将是最先检测到的错误之一。

于 2010-09-09T18:02:18.070 回答
1

SeqLike.contains 通过检查序列中等于值的元素(使用 ==)来检查值是否存在。== 需要一个 Any 所以我怀疑这就是原因。

于 2010-09-09T17:57:49.603 回答