Scala Language
För uttryck
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.