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 ofrece 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 habilita 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 diferenciar entre declaraciones y expresiones condicionales, y a aprovechar la expresividad de Kotlin para construir 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
puede usarse como una expresión que retorna un valor, no solo como una declaración de control, como en muchos lenguajes imperativos.
fun maxOf(a: Int, b: Int) = if (a > b) a else b
Esto permite escribir funciones más concisas y expresivas.
Cuando no necesitas obtener un valor, también puedes usar if
como declaración, simplemente para ejecutar código condicional:
if (isLoggedIn) {
println("Welcome back!")
}
// else es opcional si se usa como declaración
else
, no hay valorCuando if
se utiliza como expresión, el bloque else
es obligatorio.
Si lo omites, el compilador no sabrá qué valor retornar:
val result = if (x > 0) "Positive" // ❌ Error de compilación: falta `else`
if
: ¿cuándo son necesarias?-
Si una rama (
if
oelse
) tiene más de una línea, las llaves{}
son obligatorias. -
Si tiene una sola línea, pueden omitirse, aunque se recomienda mantenerlas para evitar errores al modificar el código.
-
En expresiones
if
, el valor retornado será el de la última expresión evaluada en cada rama.if como expresión simpleval result = if (x > 0)
"positive"
else
"negative"En este caso, el valor de
result
será"positive"
o"negative"
, según 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
. Además, devuelve un valor, lo que la convierte en una herramienta versátil para el control de flujo.
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"
}
when (status)
evalúa el valor destatus
y lo compara contra múltiples condiciones.- Puedes agrupar valores en una rama usando comas:
200, 201, 204 ->
. - Permite verificaciones de tipo, como
is Int
o!is String
. - El bloque
else
es obligatorio si no se cubren todos los posibles casos. - Como
when
es una expresión, puede usarse directamente en asignaciones o retornos.
Diferencias con switch
en otros lenguajes
A diferencia de estructuras como switch
en C, Java o JavaScript, Kotlin no permite ejecución por caída (fall-through) entre ramas.
No es necesario usar 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
, imprimirá:
Success
Bad Request
Esto ocurre porque la ejecución "cae" al siguiente caso si no hay un break
.
Para lograr un comportamiento equivalente al de Kotlin, se necesita 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
, solo se imprimirá:
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 aislada, y el flujo de control es más seguro, claro y fácil de mantener.
Puedes omitir el valor entre paréntesis para evaluar condiciones arbitrarias, como en un bloque if-else if
:
when {
temperature < 0 -> "Below freezing"
temperature <= 15 -> "Cold"
temperature <= 25 -> "Mild"
temperature <= 35 -> "Warm"
else -> "Hot"
}
{}
en when
- Las llaves son obligatorias si la rama contiene más de una instrucción.
- Si hay una sola expresión, se pueden omitir (aunque es recomendable incluirlas por claridad).
- En expresiones
when
, el valor retornado será el de la última expresión evaluada en cada rama.
val message = when (code) {
404 -> {
println("Not Found")
logError(code)
"Not Found" // ← Esta línea se devuelve
}
else -> "Unhandled"
}
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 (
case (a, b)
). - No soporta patrones anidados ni coincidencias estructurales complejas.
- Las condiciones tipo
case x if cond
existen, pero son experimentales y requieren habilitar-Xwhen-guards
.when con guardas (experimental)when (animal) {
is Dog -> feedDog()
is Cat if animal.mouseHunter -> feedCat()
else if animal.eatsPlants -> giveLettuce()
else -> println("Unknown animal")
}
🔁 Ejercicio: Reescribir usando when
Ejercicio
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 convierte estructuras condicionales clásicas como if
y switch
en expresiones que devuelven valores, permitiendo un estilo más expresivo, conciso y seguro, especialmente útil en funciones puras y diseños declarativos.
Tanto if
como when
pueden usarse como expresiones o declaraciones, pero cuando se usan como expresiones, producen un valor y su comportamiento es más predecible. Esta distinción es clave para escribir código idiomático en Kotlin.
🔑 Puntos clave
- Kotlin permite que
if
ywhen
se usen como expresiones que devuelven un valor, no solo como estructuras de control. - Cuando
if
es una expresión, el bloqueelse
es obligatorio. - En bloques con llaves
{}
, la última línea evaluada determina el valor de retorno. when
es una alternativa clara y poderosa a múltiplesif-else if
, y admite múltiples valores, comprobaciones de tipo y uso sin argumento.- Se requieren llaves en
when
si se ejecutan varias instrucciones en una rama. - Aunque
when
se asemeja al pattern matching, no soporta destructuring ni coincidencias estructurales complejas como Scala o Rust. - El
when
sin argumento es útil para expresar condiciones booleanas complejas de forma más declarativa.
🧰 ¿Qué nos llevamos?
Estas capacidades son especialmente valiosas al diseñar bibliotecas, donde buscamos expresar decisiones sin efectos colaterales ni estructuras verbosas. En este contexto, if
y when
no solo controlan el flujo: también producen valores, lo que facilita escribir funciones más limpias y reutilizables.
Este cambio de enfoque —ver las condiciones como expresiones evaluables y no solo instrucciones— abre la puerta a un estilo de programación más declarativo y funcional, ideal para construir bibliotecas expresivas y mantenibles.
Comprender esta diferencia nos prepara para explorar con mayor claridad temas como lambdas, funciones puras y estructuras de control más complejas. A partir de ahora, podremos elegir con mayor intención entre una declaración o una expresión, y escribir código que comunique mejor nuestras ideas.
📖 Referencias
🔥 Recomendadas
- 🎥 Cómo escribir CONDICIONALES en Kotlin: if/else, when [Curso 2024] (6m36s) en YouTube por DevExpert - Programación Android y Kotlin: 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 de Andrew Bailey, David Greenhalgh y Josh Skeen: Introducción práctica al control de flujo con
if
,else
ywhen
, usando ejemplos aplicados al proyecto bounty-board.
🔹 Adicionales
- 🌐 Conditions and loops de 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 Bruce Eckel y Svetlana Isakova: 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 Bruce Eckel y Svetlana Isakova: 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 de Dmitry Jemerov y Svetlana Isakova: 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.