Instrucciones condicionales I: if



Las estructuras de control en los lenguajes de programación permiten modificar el flujo de ejecución de las instrucciones de un programa, y como tales, las instrucciones condicionales pueden, de acuerdo con una condición definida (if) o según el valor de una variable (when), ejecutar un grupo u otro de sentencias. Otras estructuras de control de flujo son los bucles (o estructuras de repetición) que veremos más adelante.

Por tanto, las instrucciones condicionales (o estructuras de selección) nos permiten realizar una u otra lógica en función del resultado de una variable o condición y fundamentalmente son las instrucciones if y when, centrándonos ahora en la primera (para la segunda, ver Instrucciones condicionales II: when).

La palabra clave if indica que estamos en presencia de una estructura condicional; le sigue una condición entre paréntesis y termina con unas instrucciones que se ejecutarán si la condición se cumple (si es verdadera). Estas instrucciones estarán encerradas entre llaves para marcar el inicio y final del bloque salvo que exista una sola instrucción y entonces podemos omitir las llaves para hacer el código más conciso.

Como expresión, if devuelve un valor solo si la condición que hemos generado es verdadera. Podemos determinar otro valor a devolver cuando esa condición no es verdadera utilizando else. Además, cuando necesitamos concatenar varias condiciones podemos anidar varios if utilizando else if. Algunos ejemplos:
var a = 5
var b = 8

// Uso tradicional
var max1 = a
if (a < b) max1 = b
println(max1) // 8

// Con else
var max2: Int
if (a > b) {
    max2 = a
} else {
    max2 = b
}
println(max2) // 8

// Lo mismo en una expresión
val max3 = if (a > b) a else b
println(max3) // 8
Un if puede contener un bloque entre sus llaves, y en ese caso la última expresión es el valor que retorna:
val a = 5
val b = 8

val max = if (a > b) {
    println("a es mayor que b")
    a
} else {  // else requerido
    println("a no es mayor que b")
    b
}

println("max = $max") // max = 8
Es importante tener en cuenta que al utilizar if para devolver un valor o asignarlo a una variable se requiere que la expresión tenga una rama else. Puedes comprobarlo si en el código anterior eliminas el bloque else, y entonces aparece el error 'if' must have both main and 'else' branches if used as an expression.

Aunque el anidamiento de instrucciones if-else if no suele ser la práctica más correcta, es ocasiones podemos recurrir a él.
val animal = "bird"    
if (animal == "dog") {
    println("Es un perro")
} else if (animal == "cat") {
    println("Es un gato")
} else if (animal == "bird") {
    println("Es un pájaro")
} else {
    println("Es otro animal")
}
Cuando una condición se cumple no se comprueban el resto de condiciones. Por ejemplo, en el siguiente código son verdaderas dos condiciones, pero al ejecutarse un if el resto de ramas se descartan sin comprobarse:
val nota = 7
if (nota >= 7) {  // verdadera
    print("Buena nota")
} else { // esto ya no se ejecuta
    if (nota >= 5) { // verdadera
        print("Aprobado")
    } else {
        print("Suspendido")
    }
}
Es habitual que en la condición a evaluar como verdadera se utilicen operadores relacionales (> mayor, < menor, >= mayor o igual, <= menor o igual, == igual, != distinto) o incluso que esté compuesta por varias subcondiciones concatenadas por los operadores lógicos (&&, ||).
val animal = "dog"    
val raza = "labrador"

// verdadera si cumple ambas condiciones
if (animal == "dog" && raza == "labrador") {
    println("Es un perro de raza labrador")
}

// verdadera si cumple una de las condiciones
if (animal == "dog" || animal == "gato") {
    println("Es un perro o un gato")
}
Por último, una observación: las llaves alrededor de un bloque if pueden omitirse si el cuerpo de ese bloque tiene una sola línea, aunque se desaconseja a menos que el bloque se posicione en la misma línea que la condición. Esto es así porque induce a errores; por ejemplo, en el siguiente código se podría pensar equivocadamente que las dos líneas que siguen a la condición son parte del bloque if, cuando realmente solo le pertenece la primera, y la segunda línea siempre se ejecutará (recuerda que en Kotlin la sangría solo es importante para hacer un código más legible a las personas).
val edad = 21
if (edad >= 18)
    println("Eres mayor de edad")
    println("Eres menor de edad") // esto no es una parte del bloque if
En la entrada Programa para verificar si un String está vacío o es nulo puedes ver un ejemplo de un programa que utiliza if y if-else para chequear un String y para comprobar el retorno de una función.

Comentarios

Entradas populares

Recursos gratis para aprender Kotlin

I/O: entrada y salida de datos en consola

Lectura y escritura de archivos