Zoeken…


Syntaxis

  • voor {clausules} body
  • voor {clausules} opbrengstlichaam
  • voor (clausules) body
  • voor (clausules) opbrengstlichaam

parameters

Parameter Details
voor Vereist trefwoord om een for loop / begrijpend te gebruiken
clausules De iteratie en filters waarover de voor werkt.
opbrengst Gebruik dit als u een verzameling wilt maken of 'opleveren'. Als u yield wordt het retourtype van de for een verzameling in plaats van Unit .
lichaam De body van de for-expressie, uitgevoerd op elke iteratie.

Basic For Loop

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

Dit toont het herhalen van een variabele, x , van 1 tot 10 en iets met die waarde doen. Het retourtype hiervan for begrip is Unit .

Basis voor begrip

Dit toont een filter op een for-loop en het gebruik van yield om een 'reeksbegrip' te creëren:

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

De output hiervoor is:

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

A voor begrip is handig wanneer u een nieuwe collectie moet maken op basis van de iteratie en de filters.

Genest voor lus

Dit laat zien hoe u meerdere variabelen kunt herhalen:

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

(Merk op dat to hier een infix operator methode retourneert een inclusief bereik . Zie de definitie hier ).

Dit creëert de output:

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

Merk op dat dit een equivalente uitdrukking is, met haakjes in plaats van haakjes:

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

Om alle van de combinaties te krijgen in een enkele vector, kunnen we yield het resultaat en zet deze op een 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 voor begrip

Als u meerdere objecten van monadische typen heeft, kunnen we combinaties van waarden bereiken met behulp van een 'voor begrip':

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)

Het retourtype van dit blok is Unit .

Als de objecten van hetzelfde monadische type M (bijv. Option ), zal het gebruik van yield een object van het type M plaats van Unit retourneren.

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

Merk op dat het yield trefwoord niet kan worden gebruikt in het oorspronkelijke voorbeeld, waar er een combinatie van monadische typen ( Option en List ) is. Als u dit probeert, krijgt u een compilatie-type mismatch-fout.

Doorloop collecties met behulp van een For Loop

Dit laat zien hoe elk element van een kaart moet worden afgedrukt

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

Dit laat zien hoe elk element van een lijst moet worden afgedrukt

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

Zoeken naar begrip

for begrippen in Scala zijn gewoon syntactische suiker . Deze begrippen worden geïmplementeerd met de withFilter , foreach , flatMap en map van hun onderwerptypen. Om deze reden kan alleen types dat deze methoden zijn gedefinieerd worden gebruikt in een for begrip.

A for begrijpen van de volgende vorm, met patronen pN , generatoren gN en voorwaarden cN :

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

... zal de-suiker naar geneste oproepen met behulp withFilter en foreach :

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

Terwijl een for / yield expressie van de volgende vorm:

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

... zal de-suiker naar geneste oproepen met behulp withFilter en flatMap of map :

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

(Merk op dat map wordt gebruikt in het binnenste begrip, en flatMap wordt gebruikt in elk buitenlands begrip.)

A for begrip kan worden toegepast op elk type dat de methoden implementeert die vereist zijn voor de suikerloze weergave. Er zijn geen beperkingen op de retourtypen van deze methoden, zolang ze kunnen worden samengesteld.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow