Scala Language
Für Ausdrücke
Suche…
Syntax
- für {clauses} body
- für {Klauseln} ergeben Körper
- für (Klauseln) Körper
- für (Klauseln) Ertragskörper
Parameter
Parameter | Einzelheiten |
---|---|
zum | Erforderliches Schlüsselwort zur Verwendung einer for-Schleife / eines Verständnisses |
Klauseln | Die Iteration und Filter, über die das funktioniert. |
Ausbeute | Verwenden Sie dies, wenn Sie eine Sammlung erstellen oder ausgeben möchten. Die Verwendung von yield bewirkt, dass der Rückgabetyp von for eine Sammlung statt Unit . |
Karosserie | Der Rumpf des for-Ausdrucks, der bei jeder Iteration ausgeführt wird. |
Basic für Schleife
for (x <- 1 to 10)
println("Iteration number " + x)
Dies zeigt, wie Sie eine Variable x
von 1
bis 10
iterieren und mit diesem Wert etwas tun. Die Art der Rückgabe for
Verständnis ist Unit
.
Grundlegendes zum Verständnis
Dies demonstriert einen Filter für eine for-Schleife und die Verwendung von yield
, um ein 'Sequenzverständnis' zu erzeugen:
for ( x <- 1 to 10 if x % 2 == 0)
yield x
Die Ausgabe hierfür ist:
scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)
Ein Verständnis ist hilfreich, wenn Sie eine neue Sammlung basierend auf der Iteration und ihren Filtern erstellen müssen.
Für Schleife geschachtelt
Dies zeigt, wie Sie mehrere Variablen durchlaufen können:
for {
x <- 1 to 2
y <- 'a' to 'd'
} println("(" + x + "," + y + ")")
(Beachten Sie, dass to
eine Infix-Operator-Methode ist, die einen inklusiven Bereich zurückgibt. Siehe die Definition hier .)
Dadurch wird die Ausgabe erstellt:
(1,a)
(1,b)
(1,c)
(1,d)
(2,a)
(2,b)
(2,c)
(2,d)
Beachten Sie, dass dies ein äquivalenter Ausdruck ist, der Klammern anstelle von Klammern verwendet:
for (
x <- 1 to 2
y <- 'a' to 'd'
) println("(" + x + "," + y + ")")
Um alle Kombinationen in einem einzigen Vektor zusammenzufassen, können wir das Ergebnis yield
und es auf einen val
:
val a = for {
x <- 1 to 2
y <- 'a' to 'd'
} yield "(%s,%s)".format(x, y)
// a: scala.collection.immutable.IndexedSeq[String] = Vector((1,a), (1,b), (1,c), (1,d), (2,a), (2,b), (2,c), (2,d))
Monadisch für Verständnis
Wenn Sie mehrere Objekte mit monadischen Typen haben, können wir die Werte mit einem 'zum Verständnis' kombinieren:
for {
x <- Option(1)
y <- Option("b")
z <- List(3, 4)
} {
// Now we can use the x, y, z variables
println(x, y, z)
x // the last expression is *not* the output of the block in this case!
}
// This prints
// (1, "b", 3)
// (1, "b", 4)
Der Rückgabetyp dieses Blocks ist Unit
.
Wenn die Objekte vom gleichen monadischen Typ M
(z. B. Option
), wird bei Verwendung von yield
ein Objekt vom Typ M
anstelle von Unit
.
val a = for {
x <- Option(1)
y <- Option("b")
} yield {
// Now we can use the x, y variables
println(x, y)
// whatever is at the end of the block is the output
(7 * x, y)
}
// This prints:
// (1, "b")
// The val `a` is set:
// a: Option[(Int, String)] = Some((7,b))
Beachten Sie, dass das yield
nicht im ursprünglichen Beispiel verwendet werden kann, wenn eine Mischung aus monadischen Typen ( Option
und List
) vorhanden ist. Wenn Sie dies versuchen, wird ein Fehler beim Kompilieren des Typs auftreten.
Durchlaufen Sie Sammlungen mit einer for-Schleife
Dies zeigt, wie jedes Element einer Map gedruckt wird
val map = Map(1 -> "a", 2 -> "b")
for (number <- map) println(number) // prints (1,a), (2,b)
for ((key, value) <- map) println(value) // prints a, b
Dies veranschaulicht, wie jedes Element einer Liste gedruckt wird
val list = List(1,2,3)
for(number <- list) println(number) // prints 1, 2, 3
Demugaring für das Verständnis
for
Comprehensions in Scala sind nur syntaktischer Zucker . Diese Comprehensions werden implementiert , um die Verwendung von withFilter
, foreach
, flatMap
und map
Methoden ihres Faches Typen. Aus diesem Grund können nur Typen, für die diese Methoden definiert sind, for
Verständnis verwendet werden.
A for
Verständnis der folgenden Form mit Mustern pN
, Generatoren gN
und Bedingungen cN
:
for(p0 <- x0 if g0; p1 <- g1 if c1) { ??? }
... withFilter
verschachtelte Anrufe mit withFilter
und foreach
:
g0.withFilter({ case p0 => c0 case _ => false }).foreach({
case p0 => g1.withFilter({ case p1 => c1 case _ => false }).foreach({
case p1 => ???
})
})
Ein Ausdruck for
/ yield
der folgenden Form:
for(p0 <- g0 if c0; p1 <- g1 if c1) yield ???
... withFilter
verschachtelte Anrufe mit withFilter
und entweder flatMap
oder map
:
g0.withFilter({ case p0 => c0 case _ => false }).flatMap({
case p0 => g1.withFilter({ case p1 => c1 case _ => false }).map({
case p1 => ???
})
})
(Beachten Sie, dass map
im innersten Verständnis verwendet wird und flatMap
in jedem äußeren Verständnis.)
Ein for
das Verständnis kann auf jede Art angewandt werden , um die Methoden , die von der de-gezuckerten Darstellung erforderlich implementieren. Es gibt keine Einschränkungen für die Rückgabetypen dieser Methoden, sofern sie zusammengestellt werden können.