我想在我的Iterables上打电话'包含':-)
Iterable 没有 contains 方法的原因是因为它的定义方式会对方差产生直接影响 . 基本上,有两种类型的签名对它有意义:
Iterable
contains
def contains(v: Any): Boolean def contains(v: A): Boolean
第二个定义增加了类型安全性 . 但是, A (它是集合的类型参数)出现在反变量位置,这会强制集合不变 . 它可以这样定义:
A
def contains[B >: A](v: B): Boolean
但是,使用 Any ,这不会对第一个签名提供任何改进 .
Any
因此,您将看到 immutable.Seq 是共变体并使用第一个签名,而 immutable.Set 是不变的并使用第二个签名 .
immutable.Seq
immutable.Set
我不知道为什么在 Iterable 或 TraversableOnce 上没有定义 contains ,但您可以自己轻松定义它:
TraversableOnce
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))
2 回答
Iterable
没有contains
方法的原因是因为它的定义方式会对方差产生直接影响 . 基本上,有两种类型的签名对它有意义:第二个定义增加了类型安全性 . 但是,
A
(它是集合的类型参数)出现在反变量位置,这会强制集合不变 . 它可以这样定义:但是,使用
Any
,这不会对第一个签名提供任何改进 .因此,您将看到
immutable.Seq
是共变体并使用第一个签名,而immutable.Set
是不变的并使用第二个签名 .我不知道为什么在
Iterable
或TraversableOnce
上没有定义contains
,但您可以自己轻松定义它:并使用它就好像它是在Iterable上定义的: