Break, Continue y Labels

Clase 16 de 47Curso Básico de Kotlin 2019

Mientras tomas el control del flujo repitiendo una acción determinadas veces, en algún momento podemos necesitar interrumpirlos cuando una condición se cumpla. Esto se vuelve más útil al tener ciclos anidados, probablemente quisiéramos saltar de un ciclo a otro o simplemente interrumpir las o alguna de las múltiples anidaciones para después continuar con el flujo del programa.

En Kotlin podemos usar Break y Continue para lograr esto.

Break. Termina el ciclo más cercano

for (i in 1..3) { println("\ni: $i ") for (j in 1..5) { if (j.equals(3)) break println("j: $j") } }

El resultado es:

i: 1 j: 1 j: 2 i: 2 j: 1 j: 2 i: 3 j: 1 j: 2

Continue. Va a la siguiente línea de código del ciclo más cercano.

for (i in 1..3) { println("\ni: $i ") for (j in 1..5) { if (j.equals(3)) continue println("j: $j") } }

El resultado es:

i: 1 j: 1 j: 2 j: 4 j: 5 i: 2 j: 1 j: 2 j: 4 j: 5 i: 3 j: 1 j: 2 j: 4 j: 5

Labels

Podemos usar labels para controlar mejor los saltos y definir en qué ciclo queremos que inicie después de saltar. Un label será un nombre que fungirá como identificador clave para el punto y/o ciclo específico al cual deseamos saltar, lo usaremos con break y continue llamándolo por el mismo nombre definido.

La sintaxis de un label es: nombre@ Un label se llamará así: break/continue@nombre

Para entender mejor cómo funciona anidemos un for más a nuestra secuencia:

Break y Label

for (i in 1..3) { println("\ni: $i ") for (j in 1..3) { println("\nj: $j") for (k in 1..5) { if (k.equals(3)) break println("k: $k") } } }

Nos imprime lo siguiente:

i: 1 j: 1 k: 1 k: 2 j: 2 k: 1 k: 2 j: 3 k: 1 k: 2 i: 2 j: 1 k: 1 k: 2 j: 2 k: 1 k: 2 j: 3 k: 1 k: 2 i: 3 j: 1 k: 1 k: 2 j: 2 k: 1 k: 2 j: 3 k: 1 k: 2

Así se verían nuestros for’s usando un label

terminarTodoCiclo@ for (i in 1..3) { println("\ni: $i ") for (j in 1..3) { println("\nj: $j") for (k in 1..5) { if (k.equals(3)) break@terminarTodoCiclo println("k: $k") } } }

Nos imprime lo siguiente:

i: 1 j: 1 k: 1 k: 2

Cómo ves en este caso para Break y Label terminarán el ciclo donde está definido el label.

Ahora veamos cómo se comporta con Continue:

for (i in 1..3) { println("\ni: $i ") for (j in 1..3) { println("\nj: $j") for (k in 1..5) { if (k.equals(3)) continue println("k: $k") } } }

Esto es lo que imprime:

i: 1 j: 1 k: 1 k: 2 k: 4 k: 5 j: 2 k: 1 k: 2 k: 4 k: 5 j: 3 k: 1 k: 2 k: 4 k: 5 i: 2 j: 1 k: 1 k: 2 k: 4 k: 5 j: 2 k: 1 k: 2 k: 4 k: 5 j: 3 k: 1 k: 2 k: 4 k: 5 i: 3 j: 1 k: 1 k: 2 k: 4 k: 5 j: 2 k: 1 k: 2 k: 4 k: 5 j: 3 k: 1 k: 2 k: 4 k: 5

Solamente salta y no imprime cuando k=3

Continue+Label

escaparJ@ for (i in 1..3) { println("\ni: $i ") for (j in 1..3) { println("\nj: $j") for (k in 1..5) { if (k.equals(3)) continue@escaparJ println("k: $k") } } }

Nos imprime lo siguiente:

i: 1 j: 1 k: 1 k: 2 i: 2 j: 1 k: 1 k: 2 i: 3 j: 1 k: 1 k: 2

Lo que observamos es que Continue con Label hace saltar o escapar una iteración entera que en este caso es J.

Usar labels nos ayuda a controlar nuestros ciclos de una forma más eficiente, sin necesidad de utilizar nuestros propios “hacks” de código y obtener los resultados que queremos. Las situaciones que pueden presentarse son infinitas y tener este control nos ayuda codificar mucho más rápido.