Почему у Iterator есть метод содержимого, а у Iterable нет, в Scala 2.8? - PullRequest
13 голосов
/ 28 мая 2010

Я хотел бы назвать 'Содержит' в моих Итерациях: -)

Ответы [ 2 ]

23 голосов
/ 13 июля 2010

Причина, по которой 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 является инвариантным и использует вторую подпись.

5 голосов
/ 12 июля 2010

Я не знаю, почему 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))
...