2014-11-23 44 views
0

下面第一段代碼的目的是爲迭代器定義一個新的特徵,它提供了一個額外的方法,用於在迭代器前面添加一個新的元素。獲得正確的迭代器

但是,在第二個代碼段中運行代碼時,我們看到+:方法返回一個可迭代的結果,產生0的無窮大。

我在做什麼錯,我如何得到預期的行爲?

注:我添加了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

投擲猜測在那裏:會不會是重寫迭代作爲DEF意味着它重新計算新的迭代,每次,從而總是加上形式0的新的迭代,1,2,3但總是從0開始? – 2014-11-24 10:53:37

+1

在文體上說明:不需要爲'outer'引入'val',通過將'val outer'行替換爲'outer',也可以(並且可以更優雅地)顯式引用外部對象=>'。 – misberner 2014-11-24 11:18:23

+0

謝謝@misberner!我希望有人會評論如何做到這一點。我發現[this](http://docs.scala-lang.org/tutorials/tour/explicitly-typed-self-references.html)Scala文檔介紹了'outer =>'語法結構,儘管出於不同的目的。也許有更好的參考? – 2014-11-26 09:29:18

回答

0

在我的原代碼中的第一個錯誤是,outer.iterator每它的評估時間返回一個新的迭代器正如@DiegoMartinoia和@Imm所指出的那樣。

但是,如@misberner所建議的,還需要用outer =>替代val outer = this

現在,這只是我的問題的部分答案,因爲它不能解釋爲什麼第二次更改是必要的。

校正性狀碼是這樣的:

trait Iterable2[A] extends Iterable[A] { 
    outer :Iterable[A] => 
    def +:(elem :A) = new Iterable2[A] { 
    override def iterator: Iterator[A] = new Iterator[A] { 
     private[this] var virgin = true 
     private[this] val underlyingIterator = outer.iterator 
     override def hasNext: Boolean = virgin || underlyingIterator.hasNext 
     override def next(): A = { 
     if (virgin) {virgin = false; elem} 
     else underlyingIterator.next() 
     } 
    } 
    } 
} 
1

outer.iterator總會給你一個新的迭代。您需要創建一個某處藏匿,然後使用單藏匿一個,而不是創建一個新的每次:

new Iterator[A] { 
    val outerIterator = outer.iterator 
    override def hasNext = ... 
} 
+0

的確,我沒有想到這一點。但是,這不足以產生所需的行爲。它需要與@ misberner的建議相結合。 – 2014-11-26 09:48:49