DEV Community

Maximiliano Burgos
Maximiliano Burgos

Posted on

Curso Kotlin | #11. Condicional When

Bienvenido/a a otro capítulo del Curso de Kotlin! Podés consultar el curso completo desde este link que te dejo acá. Podés seguirme por LinkedIn o Twitter si querés estar al tanto de las próximas publicaciones.

En la clase anterior estudiamos las estructuras condicionales con If y usamos el ejemplo de la lotería para mostrar como podemos evaluar distintas expresiones. Pero ya en el final de la clase, notamos que el uso abusivo del else if para evaluar multiples escenarios en base a una sola variable, puede ser problemático a largo plazo. Para esto tenemos el When.

El viejo Switch de Java

Si trabajaron con Java, el antecesor de Kotlin en el aspecto de Android, saben de lo que hablo. Switch era una sentencia muy usada para evaluar distintos valores de una misma variable. Veamos como se usaba:

switch(monedas) {
        case 5:
            System.out.println("Habitación 1");
            break;
        case 10:
            System.out.println("Habitación 2");
            break;
        case 15:
            System.out.println("Habitación 3");
            break;
        case 20:
            System.out.println("Habitación 4");
            break;
        default:
            System.out.println("Habitación 5");
    }
Enter fullscreen mode Exit fullscreen mode

Este ejemplo lo extraje de este blog.) y honestamente no termino de entender cual es la relación ente habitaciones y monedas. Pero lo importante es entender la estructura: monedas es una variable que esta siendo evaluada en cinco casos distintos, de los cuales los primeros cuatro son el valor en si, y el último viene a ser una especie de “else”. System.out.println es nuestro println de toda la vida en Kotlin. La sentencia break (hablaremos más en detalle en futuras clases) salta el Switch cuando entra en alguno de los cases. Sin esto, cuando entremos al case 5, pasaríamos por el 10, 15 y 20. Era complicado explicar todo esto en sus tiempos, pero por suerte Kotlin vino a aliviar bastante el asunto. Su When, llevado al mismo ejemplo arriba, sería así:

when (monedas) {
    5 -> println("Habitación 1")
    10 -> println("Habitación 2")
    15 -> println("Habitación 3")
    20 -> println("Habitación 4")
    else -> println("Habitación 5")
}
Enter fullscreen mode Exit fullscreen mode

No se puede negar que Kotlin es un rey en la simplificación. En este caso no necesitamos un break, el salto es automático; y el default de Java es claramente el else. Traigo este ejemplo para que se vea claramente la evolución de esta sentencia.

¡Comencemos!

Podríamos hacer el juego de la lotería más interesante: un sistema de puntos que puedas ganar según la posición en que haya salido tu número. Vamos a resolverlo primero con else if. Definimos una variable score:

var score = 0
Enter fullscreen mode Exit fullscreen mode

Tiene que ser mutable porque vamos a cambiar constantemente el valor de score. Ahora vamos a determinar 5 puntajes dependiendo del resultado del array mezclado:

if(selectedNum?.toInt() == numbers[0]) {
    score =+ 5
} else if(selectedNum?.toInt() == numbers[1]){
    score =+ 4
} else if(selectedNum?.toInt() == numbers[2]){
    score =+ 3
} else if(selectedNum?.toInt() == numbers[3]){
    score =+ 2
} else if(selectedNum?.toInt() == numbers[4]){
    score =+ 1
} else {
    println("Has perdido! El numero era ${numbers[0]}")
    return
}

println("Has ganado! Tu score final es $score")
Enter fullscreen mode Exit fullscreen mode

Por un lado comprobamos que selectedNum este en las posiciones 0, 1, 2, 3 o 4 del array. Si no lo esta, devolvemos el mensaje de derrota. Usamos la sentencia return para no ejecutar todo lo demás, de esa manera cuando ganamos, podemos acceder al print de victoria con la impresión del score. Un detalle interesante es que Intellij entiende que sería una práctica mejor usar un when en este caso:

sugerencia If lift

sugerencia If lift

Y queda convertido en esto:

when {
    selectedNum?.toInt() == numbers[0] -> {
        score =+ 5
    }
    selectedNum?.toInt() == numbers[1] -> {
        score =+ 4
    }
    selectedNum?.toInt() == numbers[2] -> {
        score =+ 3
    }
    selectedNum?.toInt() == numbers[3] -> {
        score =+ 2
    }
    selectedNum?.toInt() == numbers[4] -> {
        score =+ 1
    }
    else -> {
        println("Has perdido! El numero era ${numbers[0]}")
        return
    }
}
Enter fullscreen mode Exit fullscreen mode

Es una buena conversión, pero tengamos en cuenta que no debemos ajustar un poco el código:

  • La expresión selectedNum?.toInt() == numbers[0] se puede evitar pasando la variable al when
  • Las llaves sirven cuando trabajamos con varias lineas, en este caso solo nos serviría para el else

Dicho esto, modifiquemos el código:

when (selectedNum?.toInt()) {
    numbers[0] -> score =+ 5
    numbers[1] -> score =+ 4
    numbers[2] -> score =+ 3
    numbers[3] -> score =+ 2
    numbers[4] -> score =+ 1
    else -> {
        println("Has perdido! El numero era ${numbers[0]}")
        return
    }
}
Enter fullscreen mode Exit fullscreen mode

Como ven, ahorramos muchas lineas de código, además de que se volvió más legible.

Conclusiones

Al igual que if, la sentencia when no pasará desapercibida en nuestros proyectos. La seguiremos usando en las próximas clases dado que hay muchos conceptos que se cruzan con los condicionales, como por ejemplo los rangos.

Top comments (0)