2016-03-28 12 views
0

Ich frage mich, den Kontrollfluss in einer Scala in einem For-Yield-Block. Ich sehe, dass alle Elemente zuerst den "for" -Teil und dann den "yield" -Teil durchlaufen. Warum das? Sollte es nicht für element1 für rendite sein, für rendite für element2 ...Scala For-Yield Kontrollfluss

scala> val list = List(1,2,3,4,5,6) 
list: List[Int] = List(1, 2, 3, 4, 5, 6) 

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

val t = for { 
    i <- list 
    log = println("processing " + i) 
} yield { 
    println("In yield for " + i) 
    i 
} 

// Exiting paste mode, now interpreting. 

processing 1 //All of them first go through the for block 
processing 2 
processing 3 
processing 4 
processing 5 
processing 6 
In yield for 1 // yield comes after all 
In yield for 2 
In yield for 3 
In yield for 4 
In yield for 5 
In yield for 6 
t: List[Int] = List(1, 2, 3, 4, 5, 6) 
+0

Es hängt von der Art Ihrer ersten Sache in der 'für'. Versuchen Sie 'Stream' anstelle von' List' – Dima

+0

Können Sie auf diesen Kommentar näher eingehen? Versucht Stream und es verarbeitet nur das erste Element. Warum sich die Liste so verhält, frage ich mich. – Richeek

+0

Die "Liste verhält sich genau so", weil sie so implementiert ist. 'Stream' ist in einer anderen Weise implementiert. Um '.toList' an das Ende des Snips hinzuzufügen, das" nur das erste Element verarbeitet " – Dima

Antwort

3

Ihr Code

val t = for { 
    i <- list 
    log = println("processing " + i) 
} yield { 
    println("In yield for " + i) 
    i 
} 

grob desugars in

val t = list.map { i => 
    val log = println("processing " + i) 
    (i, log) 
}.map { x => 
    x match { 
     case (i, log) => 
      println("In yield for " + i) 
    } 
} 

Von hier aus können Sie sehen, warum Sie erhalten alle "Verarbeitung ..." Nachrichten zuerst.

+0

danke. Macht Sinn – Richeek

Verwandte Themen