Kotlin desde cero: nulabilidad, bucles y condiciones

kotlin
Vistas: 33
2 0
Tiempo de Lectura:9 Minuto(s), 58 Segundo(s)

Bienvenidos al curso Kotlin desde cero: nulabilidad, bucles y condiciones, este el el segundo curso de la serie Kotlin desde cero, si quieres ver el primer da clic en el enlace: Kotlin Desde Cero: Tipos Básicos, Variables y Arreglos – MyCodes4You

1. Nulabilidad

Si eres un programador de Android, debes haber encontrado los conocidos errores NullPointerException en tu aplicación. Estos suceden cada vez que intenta llamar a un método o leer una propiedad de una referencia de objeto que es null

La buena noticia es que Kotlin puede ayudarnos a evitar este tipo de error porque es un lenguaje seguro para nulos. Esto significa que las variables no pueden tener el valor null a menos que declare explícitamente que su tipo acepta valores NULL. En otras palabras, de forma predeterminada, los tipos no pueden ser null. Veamos cómo esta característica de Kotlin puede ayudarnos a evitar errores en nuestro código.

val nombre: String = null // no se compila

Como puedes veren el codigo anterior, si asignamos null a la variable nombre el compilador marcara error. Para que el compilador permita la asignación, declara nombre como un valor que acepta valores NULL agregando ? después del tipo.

val nombre: String? = null // se compila
nombre = "Alex" // el nuevo valor es "Alex"

Ten en cuenta que si ? se inserta después de cualquier nombre de tipo, hemos indicado explícitamente al compilador que el valor del tipo puede almacenar una referencia de objeto o puede ser null es nullable. Aquí, lo hicimos con el tipo String pero funciona igual con Int?Byte?Long?MyClass?, y así sucesivamente.

El operador de llamada segura: ?.

Aprendamos más sobre cómo funciona la seguridad nula en Kotlin con un operador llamado operador de llamada segura ?..

var nombre: String? = null
print(nombre.length) // no se compila

El código anterior no se compilará porque Kotlin es un lenguaje seguro para valores NULL. Al nombre de la variable se le asigna el valor null Ahora, invocar la length de la propiedad en esa variable desencadenaría un error NullPointerException en Java. Pero el compilador de Kotlin no permitirá la invocación de esta propiedad porque la variable podría ser null El compilador no nos permitirá hacer algo que podría generar una excepción NullPointerException!

val v: String? = null
print(v?.length) // se compila y se imprime "null"

Ahora, al agregar el operador de llamada segura ?. a la variable antes de invocar la propiedad, hemos indicado explícitamente al compilador que invoque la propiedad solo si el valor no es null Si el valor es null el compilador utilizará la cadena "null" como valor para nosotros. Esto funciona también para los métodos y no sólo las propiedades.

Cuando se llama a un método de un valor que acepta valores NULL, el tipo de valor devuelto también acepta valores NULL. Así, por ejemplo, el tipo de valor devuelto de la v?.length cuando v acepta valores NULL será Int?

val v: String? = null
val len: Int? = v?.length
print(len) // will compile and print "null"

Para evitar la comprobación de nulabilidad por parte del compilador Kotlin, podemos reemplazar el operador ?. por !!.. Sin embargo, esto no se recomienda debido a la alta probabilidad de obtener errores NullPointerException si se utiliza.

val v: String? = null
val len: Int? = v!!.length
print(len) // desencadena un error NullPointerException

El operador de Elvis: ?:

Este operador ?: se llama el operador de Elvis (porque su forma se parece a la cabeza de Elvis). Se utiliza para proporcionar un valor alternativo para la variable si es null.  

val usuario = null
val nombre: String = usuario ?: "Sin Nombre"
print(nombre) // se compila e imprime "Sin Nombre"

Aquí, el compilador asignó la cadena "Sin Nombre" al nombre de la variable, porque el primer valor usuario es null Si el primer valor no era null ese valor se asignaría a la variable en su lugar.

2. Bucles

Kotlin tiene bucles while, do-while y for.

El while

Una instrucción de repetición nos permite especificar que el código debe repetir una acción mientras alguna condición sigue siendo verdadera.

Así que en Kotlin, el uso del bucle while es el mismo que en otros lenguajes como Java.

while (condición) {
    // código a ejecutar
}

while (combustible > 5) {
    vamosAConducir()
}

Siempre que la condición sea verdadera, se ejecutará el código dentro de las llaves o el cuerpo del bucle. Si la condición es false, no se ejecutará el código. En nuestro ejemplo anterior, una vez que la variable de combustible se convierte en menos de 5 litros, la condición se vuelve falsa y luego el bucle termina. En otras palabras, la ejecución del método vamosAConducir() se detiene.

El do..while Bucle

Kotlin también tiene el do..while construcción de bucle.

do {
    // ejecuta el código
} while (condición)

Esto es similar a la instrucción while En el bucle while, el programa prueba la condición del bucle al principio del bucle antes de ejecutar el cuerpo del bucle. Si la condición es false, no se ejecuta el cuerpo. Pero el bucle do-while prueba la condición después de ejecutar el cuerpo del bucle. Esto significa que el cuerpo se ejecuta al menos una vez.

El for

Un bucle for es una instrucción de repetición que nos permite recorrer en iteración los objetos mientras una condición determinada es verdadera.

for (valor in intervalo) {
    // Ejecuta código
}   

En Kotlin, la construcción del bucle for funciona con iteración en intervalos, colecciones u otros iterables (más veremos sobre estos en la próxima publicación). Los bucles For funcionan junto con el operador in que se utiliza para determinar si un valor está presente en un intervalo determinado.

for (a in 1..5) {
     print("$a ") // se imprimira  1 2 3 4 5
}

En el código anterior, estamos iterando a través de un rango cerrado de 1 a 5 e imprimiendo cada valor en el rango.

Recorrer en iteración una matriz de índice

Podemos usar la función withIndex() o la propiedad indices en una matriz para iterar sobre una matriz donde necesitamos el índice para cada elemento.

Uso de la función withIndex()

Podemos iterar sobre una matriz para acceder al índice de cada elemento llamando a la función withIndex() en la matriz, porque la función withIndex() devuelve un tipo iterable de IndexedValue para cada elemento. Esto nos permite acceder tanto al índice como al valor de cada elemento desde él.

val numerosArray = intArrayOf(1,2,3,4,5)
for ((index, value) in numerosArray.withIndex()) {
    print("$index índice valor es $value\n")
}

El código anterior imprimirá el siguiente resultado:

0 índice valor es 1
1 índice valor es 2
2 índice valor es 3
3 índice valor es 4
4 índice valor es 5

Uso de la propiedad indices

Además, podemos usar la propiedad indices en la matriz. Esto devolverá solo el intervalo de índices válidos para la matriz.

val numeros1 = intArrayOf(1,2,3,4,5)
for (index in numeros1.indices) {
    print("$index índice valor es ${numeros1[index]}\n")
}

El código anterior producirá el mismo resultado que el ejemplo anterior. Puedes ver aquí también que podemos usar el índice para acceder a un elemento de matriz, de manera similar a otros lenguajes de programación como Java.

3. Condiciones

Kotlin tiene tres tipos de sentencias de condición: el ifif..else, y when

El IF

Un if ejecuta código si una condición es true, o simplemente la omite si la condición es false. Nada especial aquí: las declaraciones if funcionan de manera similar a como lo hacen en la mayoría de los otros lenguajes de programación, incluido Java.

val numero = 20
if (numero % 2 == 0) {
    print("$number se puede dividir entre 2") // 20 se puede dividir entre 2
}

También podemos comprobar si una variable es de un tipo determinado utilizando la palabra clave is

if (numero is Int) {
    print("$number es un entero") // 20 es un entero
}   

El if..else (Instrucción)

El if..else realiza una acción si la condición es true y realiza una acción diferente si la condición es false.

val numero = 13
if (numero % 2 == 0) {
    print("$numero se puede dividir entre 2")
} else {
    print("$numero no se puede dividir entre 2") // 13 no se puede dividir entre 2
}

Una característica importante que distingue el if..else instrucción else en Kotlin de otros lenguajes de programación como Java es la capacidad de asignar una variable a partir del valor devuelto del if..else Esto es posible porque un if..else se puede usar no solo como una declaración, sino también como una expresión en Kotlin.

val numero = 13
val resultado = if (numero% 2 == 0) {
    "$number se puede dividir entre 2"
} else {
    "$number no se puede dividir entre 2"
}
print(resultado) // "13 no se puede dividir entre 2"

En el código anterior, asignamos la variable resultado con un objeto String basado en la condición de if..else Ten en cuenta que esto devolverá solo la última instrucción en un bloque de condición determinado y también que no puede usar un if sin un else como expresión.

val resultado = if (numero % 2 == 0) {
    "Divisible entre 2"
    "Numero es $numero" // only this string is returned if executed
} else {
    "No divisible entre 2"
    "Numero es $numero"
}

La expresión when

Kotlin introdujo la construcción when como reemplazo de la conocida instrucción switch que tenemos en diferentes lenguajes de programación como C++, Java, etc. when es más conciso y tiene características más potentes que la instrucción switch con la que podría estar familiarizado.

when realiza diferentes acciones en función de los valores posibles de una constante de tipo IntStringByteShorto cualquier otro objeto.

fun adivinaElNumero(numero: Int) {

    when (numero) {
        1 -> println("el numero es 1")
        2 -> println("el numero es 2")
        3 -> println("el numero es 3")
        else -> println("el numero no es ni 1, 2 o 3")
    }
}

En el código anterior, pasamos a la función adivinaElNumero() un parámetro numérico (discutiremos las funciones en Kotlin en un post posterior). A continuación, la expresión when comprueba si alguna de las bifurcaciones coincide con el valor de numero y, a continuación, ejecuta la acción en esa bifurcación. Si ninguna de las bifurcaciones era una coincidencia, se ejecuta la rama else

Otra variante de la expresión when no requiere ningún argumento, como en el ejemplo siguiente.

fun adivinaElNumero(numero: Int) {
    
    when {
        numero == 1 -> println("el numero es 1")
        numero == 2 -> println("el numero es 2")
        numero == 3 -> println("el numero es 3")
        else -> println("el numero no es ni 1, 2 o 3")
    }
}

Si queremos ejecutar más de una acción en una rama, necesitamos envolver las acciones entre llaves {}.

val numero = 2
when (numero) {
    1 -> println("el numero es 1")
    2 -> {
        // bloque de código a ejecutar
        println("el numero es 2") 
        println("es un numero par")
    }
    3 -> println("el numero es 3")
}

Además, podemos combinar los valores de prueba en una sola rama.

val numero = 2
when (numero) {
    1, 2 -> println("el numero es 1 o 2") // el numero es 1 o 2
    3 -> println("el numero es 3")
}

Aquí, la primera rama se ejecuta porque estamos probando un valor de 1 o 2.

Happy
Happy
50 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
50 %
kotlin Previous post Kotlin Desde Cero: Tipos Básicos, Variables y Arreglos
Codigo QR Next post Código de Barras y QR con PHP y La librería TC Lib Barcode
Social profiles