Ответ 1
Iterator
имеет метод toIterable
в Scala 2.8.0, но не в 2.7.7 или ранее. Это не подразумевается, но вы можете определить свое собственное неявное преобразование, если оно вам понадобится.
Предоставляет ли Scala встроенный класс, утилиту, синтаксис или другой механизм для преобразования (путем обертывания) Iterator с помощью Iterable?
Например, у меня есть Iterator [Foo], и мне нужен Iterable [Foo], поэтому в настоящее время я:
val foo1: Iterator[Foo] = ....
val foo2: Iterable[Foo] = new Iterable[Foo] {
def elements = foo1
}
Это кажется уродливым и ненужным. Какой лучший способ?
Iterator
имеет метод toIterable
в Scala 2.8.0, но не в 2.7.7 или ранее. Это не подразумевается, но вы можете определить свое собственное неявное преобразование, если оно вам понадобится.
Вы должны быть очень осторожны, когда-либо неявно преобразовывая Iterator
в Iterable
(я обычно использую Iterator.toList
- явно). Причиной этого является то, что, передав результат в метод (или функцию), который ожидает Iterable
, вы потеряете контроль над ним в той степени, в которой ваша программа может быть нарушена. Вот один пример:
def printTwice(itr : Iterable[String]) : Unit = {
itr.foreach(println(_))
itr.foreach(println(_))
}
Если Iterator
каким-то образом неявно конвертируется в Iterable
, что напечатает следующее:
printTwice(Iterator.single("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