Я хотел бы звонить, 'содержит' на моем Iterables :-)
Причина, по которой 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
инвариантен и использует вторую сигнатуру. .
Я не знаю, почему содержит
не определено в Iterable
или 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))