在Scala 2.8中,为什么迭代器有一个contains方法,而Iterable没有?

在Scala 2.8中,为什么迭代器有一个contains方法,而Iterable没有?,scala,iterator,scala-2.8,scala-collections,Scala,Iterator,Scala 2.8,Scala Collections,我想在我的Iterables上调用“contains:-)我不知道为什么在Iterable或TraversableOnce上没有定义contains,但您可以自己轻松定义它: class TraversableWithContains[A](underlying: TraversableOnce[A]) { def contains(v: Any): Boolean = underlying.exists(_ == v) } implicit def addContains[A](i

我想在我的Iterables上调用“contains:-)

我不知道为什么在
Iterable
TraversableOnce
上没有定义
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))

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

def contains(v: Any): Boolean
def contains(v: A): Boolean
第二个定义增加了类型安全性。但是,
A
,它是集合的类型参数,显示在反变位置,强制集合保持不变。可以这样定义:

def contains[B >: A](v: B): Boolean
但是,与使用
any
的第一个签名相比,这并不能提供任何改进


因此,您将看到,
不可变。Seq
是协变的,并使用第一个签名,而
不可变。Set
是不变的,并使用第二个签名。

注意:
包含
是使用
包含[A1>:a](elem:A1)
中的
来实现的(至少在Scala 2.11.8中). 我认为这与使用
Any
不同-它对
B
类型设置了一些限制-您可以传递
Any
,但不能传递已知不相关的类型。@Suma当然可以。去试试吧。如果传递不相关的类型,
A1
将被推断为公共超类型。因为所有东西都是从
Any
派生的,所以所有类型都有一个共同的超类型。你说得对。那么,有什么原因可以解释为什么签名在库中保持原样,而不是像您写的那样使用
any