作爲每the docs:
的迭代器將重新用於每個物化,這是 該方法需要一個函數,而不是直接的迭代器 的原因被創建。
流階段應該是可重用的,所以你可以實現它們不止一個。然而,給定的迭代器可以(經常)僅被使用一次。如果fromIterator
創建了引用現有迭代器的源(無論是通過名稱還是引用傳遞),則第二次嘗試實現它可能會失敗,因爲基礎迭代器將耗盡。
爲了解決這個問題,源代碼需要能夠實例化一個新的迭代器,因此fromIterator
允許您提供必要的邏輯來將其作爲供應商函數執行此操作。
下面是我們不希望發生的事情爲例:
implicit val system = akka.actor.ActorSystem.create("test")
implicit val mat = akka.stream.ActorMaterializer(system)
val iter = Iterator.range(0, 2)
// pretend we pass the iterator directly...
val src = Source.fromIterator(() => iter)
Await.result(src.runForEach(println), 2.seconds)
// 0
// 1
// res0: akka.Done = Done
Await.result(src.runForEach(println), 2.seconds)
// res1: akka.Done = Done
// No results???
這是不好的,因爲源src
不重複使用,因爲它並不會給後續運行相同的輸出。但是,如果我們懶惰地創建迭代器,它會起作用:
val iterFunc =() => Iterator.range(0, 2)
val src = Source.fromIterator(iterFunc)
Await.result(src.runForEach(println), 2.seconds)
// 0
// 1
// res0: akka.Done = Done
Await.result(src.runForEach(println), 2.seconds)
// 0
// 1
// res1: akka.Done = Done