Scala Language
Para expresiones
Buscar..
Sintaxis
- para {cláusulas} cuerpo
- para {cláusulas} cuerpo de rendimiento
- para (cláusulas) cuerpo
- para (cláusulas) ceder cuerpo
Parámetros
Parámetro | Detalles |
---|---|
para | Palabra clave requerida para usar un bucle / comprensión |
cláusulas | La iteración y los filtros sobre los que trabaja el. |
rendimiento | Use esto si quiere crear o 'producir' una colección. El uso de yield hará que el tipo de retorno de for sea una colección en lugar de Unit . |
cuerpo | El cuerpo de la expresión, ejecutado en cada iteración. |
Basic For Loop
for (x <- 1 to 10)
println("Iteration number " + x)
Esto demuestra la iteración de una variable, x
, de 1
a 10
y hacer algo con ese valor. El tipo de retorno de este for
comprensión es la Unit
.
Básico Para Comprensión
Esto demuestra un filtro en un bucle for, y el uso del yield
para crear una 'comprensión de secuencia':
for ( x <- 1 to 10 if x % 2 == 0)
yield x
La salida para esto es:
scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)
Una para la comprensión es útil cuando necesita crear una nueva colección basada en la iteración y sus filtros.
Anidado para bucle
Esto muestra cómo puedes iterar sobre múltiples variables:
for {
x <- 1 to 2
y <- 'a' to 'd'
} println("(" + x + "," + y + ")")
(Tenga en cuenta que to
aquí es un método operador infijo que devuelve un rango inclusivo . Véase la definición aquí .)
Esto crea la salida:
(1,a)
(1,b)
(1,c)
(1,d)
(2,a)
(2,b)
(2,c)
(2,d)
Tenga en cuenta que esta es una expresión equivalente, utilizando paréntesis en lugar de corchetes:
for (
x <- 1 to 2
y <- 'a' to 'd'
) println("(" + x + "," + y + ")")
Para obtener todas las combinaciones en un solo vector, podemos yield
el resultado y establecerlo en un valor 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))
Monádico para las comprensiones.
Si tiene varios objetos de tipos monádicos , podemos lograr combinaciones de los valores utilizando un 'para comprensión':
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)
El tipo de retorno de este bloque es la Unit
.
Si los objetos son del mismo tipo monádico M
(p. Ej., Option
), usar el yield
devolverá un objeto de tipo M
lugar de 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))
Tenga en cuenta que la palabra clave de yield
no se puede utilizar en el ejemplo original, donde hay una combinación de tipos monádicos ( Option
y List
). Tratar de hacerlo producirá un error de falta de coincidencia de tipo de tiempo de compilación.
Iterar a través de colecciones utilizando un bucle for
Esto demuestra cómo imprimir cada elemento de un mapa.
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
Esto demuestra cómo imprimir cada elemento de una lista
val list = List(1,2,3)
for(number <- list) println(number) // prints 1, 2, 3
Desugaring para comprensiones
for
comprensiones en Scala solo son azúcares sintácticos . Estas comprensiones se implementan utilizando los withFilter
, foreach
, flatMap
y map
de sus tipos de materias. Por esta razón, sólo los tipos que han definido estos métodos pueden ser utilizados en una for
comprensión.
A for
comprensión de la siguiente forma, con patrones pN
, generadores gN
y condiciones cN
:
for(p0 <- x0 if g0; p1 <- g1 if c1) { ??? }
... reducirá el azúcar a las llamadas anidadas con withFilter
y foreach
:
g0.withFilter({ case p0 => c0 case _ => false }).foreach({
case p0 => g1.withFilter({ case p1 => c1 case _ => false }).foreach({
case p1 => ???
})
})
Considerando que una expresión for
/ yield
de la siguiente forma:
for(p0 <- g0 if c0; p1 <- g1 if c1) yield ???
... reducirá el azúcar a las llamadas anidadas usando withFilter
y flatMap
o map
:
g0.withFilter({ case p0 => c0 case _ => false }).flatMap({
case p0 => g1.withFilter({ case p1 => c1 case _ => false }).map({
case p1 => ???
})
})
(Tenga en cuenta que el map
se usa en la comprensión más profunda, y flatMap
se usa en cada comprensión externa).
A for
comprensión se puede aplicar a cualquier tipo implementando los métodos requeridos por la representación sin azúcar. No hay restricciones en los tipos de retorno de estos métodos, siempre que sean compositivos.