Sök…


Syntax

  • för {klausuler} kropp
  • för {klausuler} avkastningskropp
  • för (klausuler) organ
  • för (klausuler) avkastningskropp

parametrar

Parameter detaljer
för Nödvändigt nyckelord för att använda en för loop / förståelse
klausuler Den iteration och filter som för fungerar.
avkastning Använd detta om du vill skapa eller "ge" en samling. Användning av yield kommer att göra att returtypen for är en samling istället för Unit .
kropp Kroppen för uttrycket, exekverad på varje iteration.

Grundläggande för ögla

for (x <- 1 to 10)
  println("Iteration number " + x)

Detta visar iterera en variabel, x , från 1 till 10 och göra något med det värdet. Retur typ av detta for förståelsen är Unit .

Grundläggande för förståelse

Detta visar ett filter på en för-loop och användningen av yield att skapa en "sekvensförståelse":

for ( x <- 1 to 10 if x % 2 == 0)
  yield x

Utmatningen för detta är:

scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)

En förståelse är användbar när du behöver skapa en ny samling baserad på iterationen och dess filter.

Nested For Loop

Detta visar hur du kan iterera över flera variabler:

for {
  x <- 1 to 2
  y <- 'a' to 'd'
} println("(" + x + "," + y + ")")

(Notera att to här är en infix operatörs metod som returnerar ett allomfattande räckvidd . Se definitionen här .)

Detta skapar utgången:

(1,a)
(1,b)
(1,c)
(1,d)
(2,a)
(2,b)
(2,c)
(2,d)

Observera att detta är ett ekvivalent uttryck med parenteser istället för parenteser:

for (
  x <- 1 to 2
  y <- 'a' to 'd'
) println("(" + x + "," + y + ")")

För att få alla kombinationer till en enda vektor kan vi yield resultatet och ställa in det till en 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))

Monadisk för förståelser

Om du har flera objekt av monadiska typer kan vi uppnå kombinationer av värdena med hjälp av en "för förståelse":

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)

Returtypen för detta block är Unit .

Om objekten är av samma monadiska typ M (t.ex. Option ) returnerar ett objekt av typ M istället för Unit användning av yield .

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))

Observera att yield sökord inte kan användas i den ursprungliga exempel, där det finns en blandning av monadiska typer ( Option och List ). Om du försöker göra detta kommer ett fel-matchningsfel för kompileringstiden att ges.

Iterera genom samlingar med hjälp av en för ögla

Detta visar hur du skriver ut varje element på en karta

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

Detta visar hur du skriver ut varje element i en lista

val list = List(1,2,3)
for(number <- list) println(number) // prints 1, 2, 3

Desugaring för förståelser

for förståelser i Scala är bara syntaktiskt socker . Dessa uppfattningar genomförs med hjälp av withFilter , foreach , flatMap och map metoder för deras motivtyper. Av denna anledning kan endast typer som har dessa metoder definieras användas for förstå.

En for förstå följande form, med mönster pN , generatorer gN och villkor cN :

for(p0 <- x0 if g0; p1 <- g1 if c1) { ??? }

... withFilter socker till kapslade samtal withFilter och foreach :

g0.withFilter({ case p0 => c0  case _ => false }).foreach({
  case p0 => g1.withFilter({ case p1 => c1  case _ => false }).foreach({
    case p1 => ???
  })
})

Medan ett uttryck for / yield av följande form:

for(p0 <- g0 if c0; p1 <- g1 if c1) yield ???

... withFilter socker till kapslade samtal withFilter och antingen flatMap eller map :

g0.withFilter({ case p0 => c0  case _ => false }).flatMap({
  case p0 => g1.withFilter({ case p1 => c1  case _ => false }).map({
    case p1 => ???
  })
})

(Observera att map används i den innersta förståelsen, och flatMap används i varje yttre förståelse.)

En for förståelse kan appliceras på vilken som helst typ genomföra de metoder som krävs av de-sockrade representation. Det finns inga begränsningar för returtyperna för dessa metoder, så länge de är komponerbara.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow