неявное или явное преобразование scala из итератора в итеративное - PullRequest
12 голосов
/ 30 апреля 2010

Предоставляет ли Scala встроенный класс, утилиту, синтаксис или другой механизм для преобразования (путем переноса) итератора в итерируемое?

Например, у меня есть Iterator [Foo], и мне нужен Iterable [Foo], поэтому в настоящее время я:

 val foo1: Iterator[Foo] = ....
 val foo2: Iterable[Foo] = new Iterable[Foo] {
   def elements = foo1
 }

Это кажется уродливым и ненужным. Какой способ лучше?

Ответы [ 2 ]

13 голосов
/ 30 апреля 2010

Iterator имеет метод toIterable в Scala 2.8.0, но не в 2.7.7 или более ранней. Это неявное, но вы можете определить свое собственное неявное преобразование, если оно вам нужно.

7 голосов
/ 01 мая 2010

Вы должны быть очень осторожны в отношении когда-либо неявно преобразования Iterator в Iterable (я обычно использую Iterator.toList - явно) Причина этого в том, что, передавая результат в метод (или функцию), который ожидает Iterable, вы теряете контроль над ним до такой степени, что ваша программа может быть повреждена . Вот один пример:

def printTwice(itr : Iterable[String]) : Unit = {
    itr.foreach(println(_))
    itr.foreach(println(_))
}

Если Iterator каким-то образом неявно преобразуется в Iterable, что будет напечатано следующее?

printTwice(Iterator.single("Hello"))

Он будет (конечно) печатать только Hello один раз. Совсем недавно trait TraversableOnce был добавлен в библиотеку коллекций, которая объединяет Iterator и Iterable. На мой взгляд, это возможно ошибка.

Мое личное предпочтение - использовать Iterator явно, где это возможно, а затем использовать List, Set или IndexedSeq напрямую. Я обнаружил, что редко могу написать метод, который действительно не зависит от типа, который передается. Один пример:

def foo(trades: Iterable[Trade]) {
  log.info("Processing %d trades", trades.toList.length) //hmmm, converted to a List

  val shorts = trades.filter(_.side.isSellShort)
  log.info("Found %d sell-short", shorts.toList.length) //hmmm, converted to a List again

  //etc
...