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.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow