Etwas orthogonal, kann dieses Verhalten mit Koroutinen erreicht werden. Es gibt mindestens eine Bibliothek für die Scala, die Koroutinen ermöglicht, können Sie es hier finden: http://storm-enroute.com/coroutines/
Hier ist ein Beispiel für den Code ist, dass du schreiben zu bekommen, was Sie wollen:
import org.coroutines._
def sideEffectingFunction = coroutine {() =>
val limit = new scala.util.Random().nextInt(10)
val seq = new scala.util.Random
var counter = 0 // mutable state is preserved between coroutine invocations
while (counter < limit) {
counter += 1
yieldval(seq.nextInt)
}
}
defined function sideEffectingFunction
@ val cr = call(sideEffectingFunction())
cr: Coroutine.Frame[Int, Unit] = Coroutine.Frame<depth: 1, live: true>
@ cr.resume
res31: Boolean = true
@ cr.value
res32: Int = 57369026
@ cr.resume
res33: Boolean = true
@ cr.value
res34: Int = -1226825365
@ cr.resume
res35: Boolean = true
@ cr.value
res36: Int = 1304491970
@ cr.resume
res37: Boolean = false
@ cr.value
java.lang.RuntimeException: Coroutine has no value, because it did not yield.
scala.sys.package$.error(package.scala:27)
org.coroutines.Coroutine$Frame$mcI$sp.value$mcI$sp(Coroutine.scala:130)
cmd38$.<init>(Main.scala:196)
cmd38$.<clinit>(Main.scala:-1)
Oder alternativ:
@ val cr = call(sideEffectingFunction())
cr: Coroutine.Frame[Int, Unit] = Coroutine.Frame<depth: 1, live: true>
@ while(cr.resume) println(cr.value)
-1888916682
1135466162
243385373
Oder im Geist der vorherigen Antwort:
@ val cr = call(sideEffectingFunction())
cr: Coroutine.Frame[Int, Unit] = Coroutine.Frame<depth: 1, live: true>
@ cr.resume
res60: Boolean = true
@ val iter = Iterator.continually(cr.value).takeWhile(_ => cr.resume)
iter: Iterator[Int] = non-empty iterator
@ iter.foreach(println)
1595200585
995591197
-433181225
220387254
201795229
754208294
-363238006
T Der Vorteil des Koroutinen-Ansatzes besteht darin, dass Sie einen veränderlichen Zustand zwischen den Aufrufen der zugrundeliegenden Nebeneffekte behalten können, die alle von der Außenwelt innerhalb einer Koroutine gut versteckt sind. Coroutinen können auch zusammengesetzt und aufgerufen werden.
Natürlich, Koroutinen geben Ihnen viel mehr Macht als nur Ihre Aufgabe zu arbeiten, so dass dies ein Overkill sein könnte, um sie nur dafür hinzuzufügen. Es ist jedoch eine handliche Technik, die Sie beachten sollten.
Vielen Dank für eine ausgezeichnete und schnelle Antwort! – satyagraha
Die letzte '.map (_. Get)' darf in neueren Versionen von Scala durch '.flatten' ersetzt werden, was eine implizite TraversableOnce CBF und den zugehörigen Iterator einführt. Ich denke, das entspricht immer noch meinen Kriterien. – satyagraha
Sie haben Recht. Ich habe das vermisst, weil das Scaladoc für "Iterator" es nicht erwähnt. Scheint wie ein Scaladoc-Bug: 'flatten 'kommt von der Anreicherungsklasse' TraversableOnce.FlattenOps' und Anreicherungen sollen von scaladoc gehandhabt werden (und viele sind es). Ich habe meine Antwort aktualisiert. –