Целью первого фрагмента кода ниже является определение нового признака для iterables, который предоставляет дополнительный метод для добавления нового элемента перед итерируемым.Получение правильного итератора
Однако при запуске кода во втором фрагменте мы видим, что метод +:
возвращает итерабельность, дающую бесконечность 0
s.
Что я делаю неправильно и как я могу получить предполагаемое поведение?
Примечание: я добавил outer
val, чтобы убедиться, что получаю правильный итератор при определении методов объекта, возвращаемого +:
; Я не знаю, как получить доступ к этому итератору иначе (Iterable2.this.iterator
не скомпилировал).
trait Iterable2[A] extends Iterable[A] {
val outer :Iterable[A] = this
def +:(elem :A) = new Iterable2[A] {
override def iterator: Iterator[A] = new Iterator[A] {
private[this] var virgin = true
override def hasNext: Boolean = virgin || outer.iterator.hasNext
override def next(): A = {
if (virgin) {virgin = false; elem}
else outer.iterator.next()
}
}
}
}
val i = new Iterable2[Int] {
override def iterator: Iterator[Int] = Iterator(1,2,3)
}
for (j <- 0 +: i) {
println(j)
}
Бросив догадку там: это может быть, что переопределение итератора как опр означает, что он пересчитывает новый итератора каждый раз, таким образом, всегда добавляя новый итератор вида- , 1,2,3, но всегда от 0? –
С стилистической нотой: вам не нужно вводить 'val' для' outer', явная ссылка на внешний объект также может (и, возможно, более элегантно) быть достигнута путем замены строки 'val outer' на' external => '. – misberner
Спасибо, @misberner! Я надеялся, что кто-то прокомментирует, как это сделать должным образом. Я нашел [this] (http://docs.scala-lang.org/tutorials/tour/explicitly-typed-self-references.html) статью о документации Scala, которая вводит синтаксическую конструкцию 'outer =>', хотя для разных целей , Может быть, есть лучшая ссылка? –