Я хотел бы назвать 'contains' на моих Iterables: -)
Почему у Iterator есть метод contains, но Iterable в Scala 2.8?
Ответ 1
Причина 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
является инвариантным и использует вторую подпись.
Ответ 2
Я не знаю, почему contains
не определено на 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))