首页 文章

为什么Iterator在Scala 2.8中有一个contains方法但是Iterable没有?

提问于
浏览
13

我想在我的Iterables上打电话'包含':-)

2 回答

  • 5

    Iterable 没有 contains 方法的原因是因为它的定义方式会对方差产生直接影响 . 基本上,有两种类型的签名对它有意义:

    def contains(v: Any): Boolean
    def contains(v: A): Boolean
    

    第二个定义增加了类型安全性 . 但是, A (它是集合的类型参数)出现在反变量位置,这会强制集合不变 . 它可以这样定义:

    def contains[B >: A](v: B): Boolean
    

    但是,使用 Any ,这不会对第一个签名提供任何改进 .

    因此,您将看到 immutable.Seq 是共变体并使用第一个签名,而 immutable.Set 是不变的并使用第二个签名 .

  • 23

    我不知道为什么在 IterableTraversableOnce 上没有定义 contains ,但您可以自己轻松定义它:

    class TraversableWithContains[A](underlying: TraversableOnce[A]) {
      def contains(v: Any): Boolean =
        underlying.exists(_ == v)
    }
    implicit def addContains[A](i: Iterable[A]) = new TraversableWithContains(i)
    

    并使用它就好像它是在Iterable上定义的:

    val iterable: Iterable[Int] = 1 to 4
    assert(iterable.contains(3))
    assert(!iterable.contains(5))
    

相关问题