2016-09-25 84 views
0

我在文件中有一組名稱。我需要實現一個不斷循環遍歷的Generator。但是,代碼在第一次傳遞後無限期掛在if (iter.hasNext)處。圓形發電機無限期懸掛

代碼

var asStream = getClass.getResourceAsStream("/firstnames/female/en_US_sample.txt") 

var source: BufferedSource = Source.fromInputStream(asStream) 
var iter: Iterator[String] = Iterator.continually(source.getLines()).flatten 

val genLastName: Gen[String] = { 
    genCannedData 
} 

def genCannedData: Gen[String] = { 
    println("Generating names: " + iter) 
    Gen.delay { 
     if (iter.hasNext) { 
     println("In if") 
     Gen.const(iter.next) 
     } 
     else { 
     println("In else") 
     Gen.const(iter.next) 
     } 
    } 
} 

樣品性能試驗

property("FirstNames") = { 
    forAll(genLastName) { 
     a => { 
     println(a) 
     a == a 
     } 
    } 
    } 

en_US_sample.txt文件內容

Abbie 
Abby 
Abigail 
Ada 
Adah 

編輯 - 臨時工作代碼

下面的代碼工作,如果我重新迭代器,但我不知道爲什麼Iterator.continually是掛?

def genCannedData: Gen[String] = { 
    Gen.delay { 
     if (iter.hasNext) { 
     Gen.const(iter.next) 
     } 
     else { 
     asStream = getClass.getResourceAsStream("/firstnames/female/en_US_sample.txt") 
     source = Source.fromInputStream(asStream) 
     iter = source.getLines() 
     Gen.const(iter.next) 
     } 
    } 
    } 

回答

1

第一次迭代後,迭代器通過source.getLines()返回false爲hasNext,這意味着空迭代返回。 Iterator.continually()持續評估source.getLines()期望下一個迭代器,但它會繼續返回空的迭代器。然後它形成一個無限循環。

+0

有沒有更好的方式來寫它,而不是像我在工作代碼中顯示的那樣重新初始化流? –

+1

創建一個全部元素的列表(通過'source.getLines()。toList')然後'Iterator.continually(theList).flatten'。這種方式只能用於內存時才能使用。否則,重新初始化流是一種方式。 – kawty