Control de bucles en Kotlin
Bucle for
El bucle for puede iterar sobre cualquier objeto que proporcione un iterador, la sintaxis es la siguiente:
for (item in collection) print(item)
El cuerpo del bucle puede ser un bloque de código:
for (item: Int in ints) {
// ……
}
Como se mencionó anteriormente, for puede iterar sobre cualquier objeto que proporcione un iterador.
Si quieres recorrer un array o una lista mediante índices, puedes hacerlo así:
for (i in array.indices) {
print(array[i])
}
Ten en cuenta que este "recorrido en un rango" se compila a una implementación optimizada y no crea objetos adicionales.
O puedes usar la función de biblioteca withIndex:
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
Ejemplo
Iterando sobre una colección:
fun main(args: Array<String>) {
val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
}
Resultado:
apple banana kiwi item at 0 is apple item at 1 is banana item at 2 is kiwi
Los bucles while y do...while
while es el bucle más básico, su estructura es:
while( 布尔表达式 ) {
//循环内容
}
Bucle do…while. En el caso de la sentencia while, si no se cumple la condición, no se puede entrar en el bucle. Pero a veces necesitamos que se ejecute al menos una vez incluso si no se cumple la condición.
El bucle do…while es similar al bucle while, con la diferencia de que el bucle do…while se ejecuta al menos una vez.
do {
//代码语句
}while(布尔表达式);
Ejemplo
fun main(args: Array<String>) {
println("----while 使用-----")
var x = 5
while (x > 0) {
println( x--)
}
println("----do...while 使用-----")
var y = 5
do {
println(y--)
} while(y>0)
}
Resultado:
----while 使用----- 5 4 3 2 1 ----do...while 使用----- 5 4 3 2 1
Retornos y saltos
Kotlin tiene tres expresiones de salto estructural:
- return. Por defecto, retorna de la función o función anónima que lo envuelve más directamente.
- break. Termina el bucle que lo envuelve más directamente.
- continue. Continúa con la siguiente iteración del bucle que lo envuelve más directamente.
En los bucles, Kotlin admite los operadores tradicionales break y continue.
fun main(args: Array<String>) {
for (i in 1..10) {
if (i==3) continue // i 为 3 时跳过当前循环,继续下一次循环
println(i)
if (i>5) break // i 为 6 时 跳出循环
}
}
Resultado:
1 2 4 5 6
Etiquetas de break y continue
En Kotlin, cualquier expresión se puede marcar con una etiqueta (label). El formato de una etiqueta es un identificador seguido del símbolo @, por ejemplo: abc@, fooBar@ son etiquetas válidas. Para etiquetar una expresión, solo tenemos que poner la etiqueta delante de ella.
loop@ for (i in 1..100) {
// ……
}
Ahora podemos usar etiquetas para restringir break o continue:
loop@ for (i in 1..100) {
for (j in 1..100) {
if (……) break@loop
}
}
Un break restringido por etiqueta salta al punto de ejecución justo después del bucle especificado por la etiqueta. continue continúa con la siguiente iteración del bucle especificado por la etiqueta.
Retorno con etiquetas
Kotlin tiene literales de función, funciones locales y expresiones de objeto. Por lo tanto, las funciones de Kotlin pueden estar anidadas. El return restringido por etiqueta nos permite retornar desde una función externa. Uno de los usos más importantes es retornar desde una expresión lambda. Recuerda cuando escribimos esto:
fun foo() {
ints.forEach {
if (it == 0) return
print(it)
}
}
Esta expresión return retorna de la función que la envuelve más directamente, es decir, foo. (Ten en cuenta que este retorno no local solo se admite en expresiones lambda pasadas a funciones inline). Si necesitamos retornar desde una expresión lambda, debemos ponerle una etiqueta y usarla para restringir el return.
fun foo() {
ints.forEach lit@ {
if (it == 0) return@lit
print(it)
}
}
Ahora solo retornará desde la expresión lambda. Normalmente es más conveniente usar la etiqueta implícita. Dicha etiqueta tiene el mismo nombre que la función que recibe la lambda.
fun foo() {
ints.forEach {
if (it == 0) return@forEach
print(it)
}
}
Alternativamente, podemos usar una función anónima en lugar de la expresión lambda. La sentencia return dentro de una función anónima retornará desde la propia función anónima.
fun foo() {
ints.forEach(fun(value: Int) {
if (value == 0) return
print(value)
})
}
Cuando se quiere retornar un valor, el analizador prefiere el return restringido por etiqueta, es decir:
return@a 1
Significa "retornar 1 desde la etiqueta @a", no "retornar una expresión etiquetada (@a 1)".
Otras extensiones