Control de Flujo: if, when, for y while

Expresión If

El primer control de flujo que vamos a ver en Kotlin es if, el cual es una expresión, por tanto tiene que devolver un valor. Por lo tanto no hay un operador ternario.

// Uso tradicional
var max = a 
if (a < b) max = b

// Con else 
var max: Int
if (a > b) {
    max = a
} else {
    max = b
}
 
// Como expresión
val max = if (a > b) a else b

Las ramas if pueden ser bloques, y la última expresión es el valor de un bloque:

 val max = if (a > b) {
    print("Choose a")
    a
} else {
    print("Choose b")
    b
}

Si estás usando if como una expresión en lugar de como una declaración (por ejemplo, devolviendo su valor o asignandoló a una variable), la expresión requiere de una rama else.

Expresión When

Otro control de flujo sería when, el cual reemplaza el operador switch de los lenguajes C-like. Su forma más simple es la siguiente:

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("x no es ni 1 ni 2")
    }
}

when relaciona su argumento con todas las ramas secuencialmente hasta que alguna rama cumple la condición. when puede utilizarse tanto como expresión como una declaración. Si se usa como una expresión, el valor de que satisface la condición será el valor de toda la expresión. Si se usa como una declaración, los valores de las ramas individuales se ignoran. Al igual que if, cada rama puede ser un bloque, y su valor es el valor de la última expresión en el bloque.

La rama else se evalúa si ninguna de las otras condiciones cumplen la condición. Si when se utiliza como una expresión, la rama else es obligatoria, a menos que el compilador pueda comprobar que todos los casos posibles están expuestos en todas las ramas de condiciones (, por ejemplo, la clase enum y los subtipos de las sealed class).

Si muchos casos se deben gestionar del mismo modo, las ramas de condiciones pueden combinarse con una coma:

when (x) {
    0, 1 -> print("x es 0 o 1")
    else -> print("x es distinto de 0 o 1")
}

Podemos utilizar expresiones arbitrarias (no solo constantes) como ramas de condiciones:

when (x) {
    parseInt(s) -> print("s codifica a x")
    else -> print("s no codifica a x")
}

También se puede comprobar si un valor está dentro de un rango o de una colección:

when (x) {
    in 1..10 -> print("x está en el rango")
    in miColeccion -> print("x está en la colección")
    !in 10..20 -> print("x no está en el rango")
    else -> print("No es ninguna de las anteriores opciones")
}

Otra posibilidad es comprobar si un valor es de un tipo o no. Gracias a los smart casts, puedes acceder a los métodos y propiedades de un tipo sin ninguna comprobación adicional.

fun comprobarPrefijo(x: Any) = when(x) {
    is String -> x.startsWith("Prefijo")
    else -> false
}

when puede utilizarse también como reemplazo de una cadena if-else. Si no se proporciona un argumento, las ramas de condiciones son básicamente expresiones booleanas, y una rama se ejecuta cuando su condición se cumple.

when {
    x.isOdd() -> print("x es impar")
    x.isEven() -> print("x es par")
    else -> print("x es otra cosa")
}

Es posible asignarle el valor de un when a una variable:

fun Request.getBody() =
        when (val response = executeRequest()) {
            is Success -> response.body
            is HttpError -> throw HttpException(response.status)
        }

Bucles For

Para el control de flujo también existen los bucles. Un bucle for repite una operación en función del iterador que proporciones.

La sintaxis es la siguiente:

for (item in collection) print(item)

Aunque también se puede usar un bloque:

for (item: Int in ints) {
    // ...
}

Para iterar a través de un rango de números, utiliza una expresión de rango:

for (i in 1..3) {
    println(i)
}
for (i in 6 downTo 0 step 2) {
    println(i)
}

Un bucle for sobre un rango o un array se compila a un bucle basado en índices que no crea un objeto iterator.

Para iterar a través de un array o una lista con un índice se haría del siguiente modo:

for (i in array.indices) {
    println(array[i])
}

Alternativamente, puedes utilizar la función librería withIndex:

for ((index, value) in array.withIndex()) {
    println("El elemento $index es $value")
}

Bucles While

while y do..while funcionan como en otros lenguajes:

while (x > 0) {
    x--
}

do {
    val y = retrieveData()
} while (y != null) // 'y' es visible

Break y Continue en bucles

Kotlin soporta los operadores clásicos break y continue.

Compartir

Tipos Básicos Kotlin
Tipos Básicos
Return y Jump

Entradas relacionadas

Return y Jump

Modismos Kotlin

Modismos

Sintaxis Básica Kotlin

Sintaxis Básica

Menú