Scala Language
Voor uitdrukkingen
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.