Return y Jump

Kotlin tiene estas tres expresiones:

  • return. Por defecto devuelve una función o una función anónima.
  • break. Finaliza el bucle.
  • continue. Continua al siguiente paso en el bucle.

Todas esas expresiones pueden utilizarse como parte de expresiones más largas:

val s = persona.nombre ?: return

El tipo de esas expresiones es el Nothing type (tipo nada).

Etiquetas Break y Continue

Cualquier expresión en Kotlin puede ser marcada con una label. Las etiquetas tienen la forma de un identificador seguido del signo @. Por ejemplo: abc@, miExpresion@ son etiquetas válidas. Para etiquetar una expresión, coloca una etiqueta delate de ella:

loop@ for (i in 1..100) {
    // ...
}

Así, podemos utilizar break o continue con una etiqueta:

loop@ for (i in 1..100) {
    for (j in 1..100) {
        if (...) break@loop
    }
}

Un break con una etiqueta, salta a un punto de ejecución tras el bucle marcado con una etiqueta. Un continue procede a la siguiente iteración de ese bucle.

Return en las Etiquetas

Puedes anidar funciones y expresiones de objetos. return nos permite devolver desde una función exterior. El caso más importante es el retorno de una expresión lambda.

fun printTercerValor() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) // return no local de printTercerValor()
        print(it) // Este punto es alcanzable
    }
    println("Este punto es inalcanzable")
}

Si necesitamos un return de una expresión lambda, tenemos que etiquetarla:

fun printTercerValor() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // return local al que invoca el lambda
        print(it)
    }
    print(" completado con una etiqueta explícita")
}

Algunas veces es mejor utilizar etiquetas implícitas, es decir, etiquetas que tienen el mismo nombre que la función a la que se le pasa la lambda.

fun printTercerValor() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // return local al que invoca la función anónima
        print(it)
    }
    print(" completado con una etiqueta implícita")
}

Alternativamente, podemos reemplazar la expresión lambda con una función anónima. Una declaración return en una función anónima retornará desde la propia función anónima.

fun printTercerValor() {
    listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
        if (value == 3) return  // return local al que invoca la función anónima
        print(value)
    })
    print(" completado con una función anónima")
}

Ten en cuenta que el uso de returns locales en los tres ejemplos anteriores es similar al uso de continue en los bucles. No hay un equivalente directo para break, pero puede ser simulado añadiendo otra lambda anidada y un return no local:

fun printTercerValor() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop // return no local desde el lambda
            print(it)
        }
    }
    print(" completado desde un bucle anidado")
}

Cuando devuelvas un valor, se da preferencia a la etiqueta return utilizada:

return@a 1

La expresión anterior significa “devuelve 1 en la etiqueta @a“, por lo que no sería “devuelve la expresión etiquetada como (@a 1)“.

Compartir

Control de Flujo Kotlin
Control de Flujo: if, when, for y while
Paquetes e Imports Kotlin
Paquetes e Imports

Entradas relacionadas

Control de Flujo Kotlin

Control de Flujo: if, when, for y while

Menú