代码之家  ›  专栏  ›  技术社区  ›  Seth Tisue Arthur Hjorth

斯卡拉:为什么序列包含取任意参数,而不是序列类型的参数?

  •  21
  • Seth Tisue Arthur Hjorth  · 技术社区  · 14 年前

    例如,为什么 List(1,2,3,4).contains("wtf")

    3 回复  |  直到 14 年前
        1
  •  23
  •   Daniel C. Sobral    14 年前

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

    比如说, Set 包含 坐飞机 A 任何 .

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

    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 ==)
                          ^
    
        2
  •  4
  •   Dave Griffith    14 年前

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

    大多数Java bug查找工具都包含检测不可能存在的非类型化相等用法的测试。(我在IntelliJ IDEA中编写了检查来完成这项工作。)我毫不怀疑,当Scala bug查找工具上线时,这些将是最先发现的bug之一。

        3
  •  1
  •   JacquesB    14 年前

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