Expresiones condicionales
⏱ Dedicación recomendada: 0 minutos
Esto considera el contenido visible y relevante, e ignora texto colapsado o marcado como opcional.
r8vnhill/intro-kt
Las estructuras condicionales son uno de los pilares del control de flujo en cualquier lenguaje de programación.
Sin embargo, Kotlin adopta una perspectiva más expresiva y funcional que lenguajes imperativos tradicionales como Java, al permitir que construcciones como if
y when
no sean solo declaraciones, sino también expresiones que devuelven valores.
Este enfoque promueve un estilo de programación más conciso, declarativo y alineado con la escritura de funciones puras y reutilizables. En esta lección aprenderemos a distinguir entre declaraciones y expresiones condicionales, y a aprovechar la expresividad de Kotlin para escribir funciones más limpias y mantenibles.
También exploraremos el uso idiomático de when
, una alternativa poderosa a múltiples if
anidados, y discutiremos sus diferencias con el pattern matching en lenguajes como Scala o Rust.
🔀 Expresión if
En Kotlin, if
no se limita a controlar el flujo del programa: también puede usarse como una expresión que retorna un valor.
Esto lo diferencia de muchos lenguajes imperativos, donde if
es únicamente una declaración.
fun maxOf(a: Int, b: Int) = if (a > b) a else b
Este enfoque permite escribir funciones más concisas y expresivas.
Cuando no necesitas obtener un valor, también puedes usar if
como una declaración, simplemente para ejecutar código condicional:
if (isLoggedIn) {
println("Welcome back!")
}
// El bloque else es opcional cuando se usa como declaración
Sin else
, no hay valor
Cuando usas if
como una expresión —es decir, para producir un valor—, el bloque else
es obligatorio.
Si lo omites, el compilador no sabrá qué valor debe retornar cuando la condición sea falsa, y generará un error.
val result = if (x > 0) "Positive" // ❌ Error de compilación: falta `else`
Llaves en if
: ¿cuándo son necesarias?
-
Si una rama (
if
oelse
) contiene más de una instrucción, las llaves{}
son obligatorias. -
Si tiene una sola instrucción, pueden omitirse —aunque es recomendable mantener las llaves para evitar errores al modificar el código en el futuro.
-
Cuando se usa
if
como expresión, el valor retornado es el de la última expresión evaluada en cada rama.if como expresión simpleval result = if (x > 0)
"positive"
else
"negative"En este ejemplo,
result
será"positive"
o"negative"
dependiendo de la condición.
Con llaves, se aplica la misma lógica:if como expresión con efectos colateralesval result = if (x > 0) {
println("Evaluating...")
"positive"
} else {
println("Evaluating...")
"negative"
}Aquí, cada rama imprime un mensaje y luego retorna una cadena como resultado.
🎛️ Expresión when
La expresión when
en Kotlin es una alternativa concisa, segura y expresiva a cadenas de if-else if
.
A diferencia de muchas construcciones similares en otros lenguajes, when
produce un valor, por lo que puede utilizarse en asignaciones o retornos.
when (status) {
200, 201, 204 -> "Success"
400 -> "Bad Request"
404 -> "Not Found"
500 -> "Internal Server Error"
"timeout" -> "The request timed out"
is Int -> "Unhandled status code: $status"
!is String -> "Unknown type"
else -> "Unhandled string: $status"
}
¿Qué acabamos de hacer?
when (status)
compara el valor destatus
contra múltiples condiciones.- Puedes agrupar valores en una misma rama usando comas:
200, 201, 204 ->
. - Permite realizar verificaciones de tipo con
is
y!is
. - El bloque
else
es obligatorio si no se cubren todos los posibles casos. - Como
when
es una expresión, puede usarse en contextos como asignaciones, retornos o inicializaciones.
Diferencias con switch
en otros lenguajes
switch
en otros lenguajesA diferencia de estructuras como switch
en C, Java o JavaScript, Kotlin no permite ejecución por caída (fall-through) entre ramas.
Esto significa que no necesitas escribir break
para evitar que se ejecuten múltiples bloques.
Por ejemplo, en Java:
switch (status) {
case 200:
System.out.println("Success");
case 400:
System.out.println("Bad Request");
}
Si status
es 200
, se imprimirá:
Success
Bad Request
Esto ocurre porque la ejecución "cae" en la siguiente rama al no encontrar un break
.
Para evitar este comportamiento en Java, necesitas agregar break
explícitamente:
switch (status) {
case 200:
System.out.println("Success");
break;
case 400:
System.out.println("Bad Request");
break;
}
Ahora sí, si status
es 200
, se imprimirá solo:
Success
En Kotlin, este es el comportamiento por defecto:
when (status) {
200 -> println("Success")
400 -> println("Bad Request")
}
No existe la posibilidad de fall-through. Cada rama es completamente aislada, lo que hace que el flujo de control sea más seguro, claro y fácil de mantener.
También puede usarse sin argumento
Puedes omitir el valor entre paréntesis en when
para evaluar condiciones arbitrarias, como lo harías con una cadena de if
/ else if
:
when {
temperature < 0 -> "Below freezing"
temperature <= 15 -> "Cold"
temperature <= 25 -> "Mild"
temperature <= 35 -> "Warm"
else -> "Hot"
}
Este estilo es útil cuando necesitas evaluar expresiones booleanas distintas que no dependen de un mismo valor.
Uso de llaves {}
en when
- Las llaves son obligatorias si una rama contiene más de una instrucción.
- Si hay una sola expresión, pueden omitirse.
- En expresiones
when
, el valor de retorno será el de la última expresión evaluada en cada rama.
val message = when (code) {
404 -> {
println("Not Found")
logError(code)
"Not Found" // ← Este valor se devuelve
}
else -> "Unhandled"
}
Diferencias con pattern matching real
Aunque when
tiene una sintaxis similar al pattern matching de lenguajes como Scala o Rust, sus capacidades son más limitadas:
- No permite destructuración directa, como
case (a, b)
en Scala. - No soporta patrones anidados ni coincidencias estructurales complejas.
- No permite hacer coincidir constructores de tipos algebraicos de forma declarativa.
🛡 when
guards
A partir de Kotlin 2.2.0, es posible agregar condiciones adicionales a una rama de when
usando un guard con la palabra clave if
. Esto permite combinar verificación de tipo y predicados personalizados en una misma rama, lo que aumenta la expresividad del control de flujo.
when (status) {
is Int if status in 200..299 -> "Success"
is Int if status in 400..499 -> "Client Error"
is Int if status >= 500 -> "Server Error"
else -> "Unknown"
}
¿Qué acabamos de hacer?
- Primero se verifica si
status
es unInt
. - Luego, se evalúa la condición del
if
. - Esta combinación actúa como un filtro: el valor debe cumplir ambas condiciones para que se ejecute la rama.
- Si ninguna coincide, se evalúa la rama
else
.
🔁 Ejercicio: Reescribir usando when
Reescribe la función login
utilizando una expresión when
en lugar de múltiples if
.
fun login(username: String, password: String): Boolean {
if (loginAttempts >= maxLoginAttempts) {
return false
}
if (isValidPassword(password)) {
loginAttempts = 0
return true
}
loginAttempts++
return false
}
Solución
fun login(username: String, password: String): Boolean = when {
loginAttempts >= maxLoginAttempts -> false
isValidPassword(password) -> {
loginAttempts = 0
true
}
else -> {
loginAttempts++
false
}
}
🎯 Conclusiones
Kotlin transforma estructuras condicionales tradicionales como if
y switch
en expresiones que retornan valores, promoviendo un estilo más conciso, expresivo y seguro.
Este enfoque es especialmente útil en funciones puras y diseños declarativos, donde buscamos reducir efectos colaterales y aumentar la claridad del código.
Desde Kotlin 2.2.0, la expresividad del lenguaje se ve reforzada con los llamados when
guards, que permiten combinar verificaciones de tipo y condiciones personalizadas en una misma rama, acercando a when
a un verdadero patrón de filtrado.
Tanto if
como when
pueden usarse como expresiones o declaraciones. La distinción es importante:
- Como declaraciones, controlan el flujo.
- Como expresiones, producen un valor y pueden usarse en asignaciones o retornos, lo que abre la puerta a un estilo más funcional.
🔑 Puntos clave
- Kotlin permite que
if
ywhen
se usen como expresiones que retornan valores. - Cuando
if
es una expresión, el bloqueelse
es obligatorio. - En ramas con llaves
{}
, se retorna la última expresión evaluada. when
es una alternativa poderosa a cadenasif-else if
, con soporte para múltiples valores, verificaciones de tipo y uso sin argumento.- Desde Kotlin 2.2.0,
when
admite guards, lo que permite escribir condiciones aún más expresivas. - Aunque
when
recuerda al pattern matching, no soporta coincidencias estructurales complejas como Scala o Rust. - El
when
sin argumento permite expresar condiciones booleanas independientes de manera declarativa.
🧰 ¿Qué nos llevamos?
Estas capacidades son especialmente valiosas al diseñar bibliotecas reutilizables, donde buscamos expresar decisiones sin estructuras verbosas ni efectos colaterales.
En este contexto, if
y when
no solo controlan el flujo: también producen valores que pueden integrarse fácilmente en funciones puras.
Adoptar este enfoque —ver las condiciones como expresiones evaluables— permite escribir código más claro, mantenible y alineado con un estilo declarativo.
Comprender esta diferencia nos prepara para abordar con solidez temas como lambdas, funciones puras y estructuras de control avanzadas.
📖 ¿Con ganas de más?
🔥 Referencias Recomendadas
- 🎥 “Cómo escribir CONDICIONALES en Kotlin: if/else, when [Curso 2024]” (6m36s) en YouTube por :Video introductorio y didáctico sobre
if
ywhen
como expresiones y declaraciones. Ideal para quienes inician en programación y quieren entender cómo expresar decisiones condicionales en el flujo del código. - 📕 “Conditionals” en Kotlin Programming: The Big Nerd Ranch Guide por :Introducción práctica al control de flujo con
if
,else
ywhen
, usando ejemplos aplicados al proyecto bounty-board.
🔹 Referencias Adicionales
- 🌐 “Conditions and loops” en la documentación oficial de Kotlin:Guía completa y actualizada sobre
if
,when
y bucles. Ideal como referencia rápida, aunque incluye temas más avanzados que aún no se abordan en el curso. - 📕 “when Expressions” (pp. 187–192) en Atomic Kotlin por :Este capítulo ofrece una introducción clara y progresiva al uso de
when
como expresión, destacando su ventaja frente a múltiplesif-else
en términos de legibilidad y expresividad. Explora desde casos simples hasta condiciones con conjuntos y tipos, reforzando su utilidad para retornar valores, agrupar condiciones y escribir código más declarativo y mantenible en bibliotecas funcionales. - 📕 “If Expressions” (pp. 39–43) en Atomic Kotlin por :Introducción muy básica al uso de
if
como expresión en Kotlin, pensada para personas nuevas en programación. Destaca su utilidad para escribir funciones concisas y declarativas. - 📕 “Kotlin Basics” (pp. 17–43) en Kotlin in Action por :Presenta
if
ywhen
como expresiones con valor de retorno, más expresivas y poderosas que sus equivalentes en Java, lo que facilita un estilo de control de flujo más idiomático.