Curso Kotlin | #11. Condicional When
Tags: beginners, spanish, kotlin, tutorial
Published: 2022-12-15 12:13:48

Bienvenido/a a otro capítulo del Curso de Kotlin! Podés consultar el curso completo desde [este link](https://github.com/maxwellnewage/kotlin-course) que te dejo acá. Podés seguirme por [LinkedIn](https://www.linkedin.com/in/maximilianoburgos/) o [Twitter](https://twitter.com/maxwellnewage) 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:

```java
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");
    }
```

Este ejemplo lo extraje de este [blog](https://javautodidacta.es/como-funciona-un-switch-en-java/#:~:text=Un%20switch%20en%20Java%20es,me%20canso%20de%20decirlo%20%F0%9F%99%82%20).) 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í:

```kotlin
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")
}
```

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:

```kotlin
var score = 0
```

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:

```kotlin
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")
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0131sy0ifdd2duf56vzc.png)


![sugerencia If lift](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9pf61irh3mvnxxu7wlf.png)

Y queda convertido en esto:

```kotlin
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
    }
}
```

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:

```kotlin
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
    }
}
```

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.