2013-05-11 5 views
10

Ich lese durch Scala for the Impatient und ich bin auf etwas gestoßen, das mich am Kopf kratzen lässt.Rückgabetyp von Scala für/Ertrag

Der folgende Code gibt ein String:

scala> for (c<-"Hello"; i <- 0 to 1) yield (c+i).toChar 
res68: String = HIeflmlmop 

Aber das gibt einen Vektor:

scala> for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar 
res72: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p) 

Der Text dieser beiden Beispiele vorhergehenden liest ...

„Wenn der Körper Wenn die for-Schleife mit yield beginnt, erstellt die Schleife eine Sammlung von Werten, eine für jede Iteration ... Diese Art von lo Op wird als Verständnis bezeichnet. Die erzeugte Sammlung ist mit dem ersten Generator kompatibel.

Wenn die erzeugte Sammlung mit dem ersten Generator kompatibel ist, dann ist, warum nicht das zweite Beispiel eine Art von Range, wie in den folgenden Rückkehr:

scala> val range = 0 to 1 
range: scala.collection.immutable.Range.Inclusive = Range(0, 1) 

Oder bin ich falsch interpretiert ganz, was die Text bedeutet "... die generierte Sammlung ist mit dem ersten Generator kompatibel".

+0

Werfen Sie einen Blick auf [dieser überlegenen Antwort] (http://stackoverflow.com/a/1716558/406435) auf bessere Sicht zu bekommen, wie es funktioniert. Und [hier] (http://www.devoxx.de)com/display/FR13/Martin + Odersky) (ab 42:40 Uhr) Martin Odersky selbst erläutert Geschichte, Motivation und Umsetzung von Scala-Sammlungen. – senia

Antwort

4

For-Comprehensions sind auf eine Reihe von map, flatMap und filter Operationen entuugariert.

Wenn Sie map auf einem Range verwenden, erhalten Sie eine Vector Ausgabe:

scala> 0 to 2 map (x => x * x) 
res12: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 4) 

Dies liegt daran, ein Range eine sehr einfache Art Sammlung ist, dass im Wesentlichen nur zwei drei Zahlen: ein Anfang Wert, ein Endwert und ein Schritt. Wenn Sie sich das Ergebnis der obigen Abbildung ansehen, können Sie sehen, dass die resultierenden Werte nicht durch etwas vom Typ Range dargestellt werden können.

0

in diesem for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar Verständnis, der erste Generator Typ ist scala.collection.immutable.Range.Inclusive die Ausbeute Ergebnisvektor ist der Typ scala.collection.immutable.IndexedSeq [Int] und wenn überprüfen Sie die Klasse Bereich: http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Range

es zeigt Bereich erstreckt/mixin die IndexedSeq. Der Super-Typ IndexedSeq ist kompatibel mit dem Untertyp Bereich.

Wenn das Ergebnis nicht durch einen Bereich dargestellt werden kann (wie in der vorherigen Antwort erklärt), wird nach dem Super-Typ gesucht, um das Ergebnis darzustellen.

enter image description here