Kotlin desde cero: Nulabilidad, bucles y condicionales
Spanish (Español) translation by Ruben Solis (you can also view the original English article)
Kotlin es un lenguaje de programación moderno que compila a Java bytecode. Es gratuito y de código abierto, y promete hacer que la codificación para Android sea aún más divertida.
En el artículo anterior, aprendiste sobre variables, tipos simples, arrays, comentarios e inferencia de tipos en Kotlin. En este tutorial, continuaremos aprendiendo el lenguaje al observar la nulabilidad, los bucles y los condicionales en Kotlin.
1. Nulabilidad
Si eres un programador de Android, debes haber encontrado los infames errores de NullPointerException en tu aplicación. Esto sucede cuando intentas 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 errores que recibimos porque es un lenguaje seguro contra valores null. Eso significa que las variables no pueden tener el valor null a menos que declare explícitamente que su tipo puede ser null. En otras palabras, por defecto, los tipos no pueden ser null. Veamos cómo esta característica de Kotlin puede ayudarnos a evitar errores en nuestro código.
1 |
val name: String = null // will not compile |
Como puedes ver arriba, si asignamos null a la variable name, el compilador se quejará. Para que el compilador permita la asignación, declara name como un nullable agregando ?despues del tipo
1 |
val name: String? = null // will compile |
2 |
name = "Chike" // new value is "Chike" |
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 a un objeto o puede ser null— es nullable. Aquí lo hicimos con el tipo String, funciona igual con Int?, Byte?, Long?, MyClass?, y así sucesivamente.
El operador de llamada segura: ?.
Vamos a aprender más acerca de seguridad contra valores null en Kotlin con un operador llamado operador de llamada segura ?..
1 |
var name: String? = null |
2 |
print(name.length) // will not compile |
El código anterior no compilará porque Kotlin es un lenguaje seguro contra valores null. A la variable name se le asigna el valor null. Ahora, invocar la propiedad length 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 un NullPointerException!
1 |
val v: String? = null |
2 |
print(v?.length) // will compile and print "null" |
Ahora agregando 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 usará la cadena "null" como valor para nosotros. Esto también funciona para métodos y no solo para propiedades.
Cuando llamas a un método de un nullable, el tipo de valor devuelto también será nullable. Así que, por ejemplo, el tipo de valor devuelto de la expresión v?.length cuando v es nullable será Int?.
1 |
val v: String? = null |
2 |
val len: Int? = v?.length |
3 |
print(len) // will compile and print "null" |
Para omitir la comprobación de nulabilidad por parte del compilador de Kotlin, podemos reemplazar el operador ?. con !!.. Sin embargo, esto no se recomienda, debido a la alta probabilidad de obtener errores de NullPointerException si se usa.
1 |
val v: String? = null |
2 |
val len: Int? = v!!.length |
3 |
print(len) // triggers a NullPointerException error |
El operador Elvis: ?:
Este operador ?: se llama operador Elvis (porque su forma se parece a la cabeza de Elvis). Se utiliza para proporcionar un valor alternativo a la variable si es null.
1 |
val username = null |
2 |
val name: String = username ?: "No name" |
3 |
print(name) // will compile and print "No name" |
Aquí, el compilador asignó la cadena "No name" a la variable name, porque el primer valor de username es null. Si el primer valor no es null, ese valor se asignará a la variable en su lugar.
2. Bucles
Kotlin tiene bucles while, do-while y for.
El bucle while
Una sentencia de repetición nos permite especificar que el código debe repetir una acción mientras alguna condición sea verdadera.
Entonces, en Kotlin, usar el bucle while es igual que en otros lenguajes como Java.
1 |
while (condition) { |
2 |
// execute code here
|
3 |
}
|
4 |
|
5 |
while (fuel > 5) { |
6 |
driveMeAroundLagos() |
7 |
}
|
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 falsa, el código no se ejecutará. En nuestro ejemplo anterior, cuando la variable fuel (combustible) se vuelve inferior a 5 litros, la condición se vuelve falsa y luego el bucle termina. En otras palabras, la ejecución del método driveMeAroundLagos() se detiene.
El bucle do..while
Kotlin también tiene la construcción de bucle do.. while.
1 |
do { |
2 |
// execute code here
|
3 |
} while (condition) |
Esto es similar a la sentencia 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 falsa, el cuerpo no se ejecuta. 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 bucle for
Un bucle for es una sentencia de repetición que nos permite iterar sobre objetos mientras una condición dada es verdadera.
1 |
for (value in range) { |
2 |
// Execute code
|
3 |
}
|
En Kotlin, la construcción de bucle for funciona con iteración sobre rangos, colecciones u otros iterables (explicaré más sobre esto 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 rango determinado.
1 |
for (a in 1..5) { |
2 |
print("$a ") // will print 1 2 3 4 5 |
3 |
}
|
En el código anterior, estamos iterando a través de un rango cerrado de 1 a 5 e imprimimos cada valor en el rango.
Iterando sobre un array de índices
Podemos usar la función withIndex() o la propiedad de indices en un array para iterar sobre un array donde necesitamos el índice para cada elemento.
Usando la función withIndex()
Podemos iterar sobre un array para acceder al índice de cada elemento llamando a la función withIndex() en el array, porque la función withIndex() devuelve un iterable de tipo IndexedValue para cada elemento. Esto nos permite acceder tanto al índice como al valor de cada elemento.
1 |
val numbersArray = intArrayOf(1,2,3,4,5) |
2 |
for ((index, value) in numbersArray.withIndex()) { |
3 |
print("$index index value is $value\n") |
4 |
}
|
El código anterior imprimirá el resultado a continuación:
1 |
0 index value is 1 |
2 |
1 index value is 2 |
3 |
2 index value is 3 |
4 |
3 index value is 4 |
5 |
4 index value is 5 |
Usando la propiedad de indices
Además, podemos usar la propiedad de indices en el array. Esto devolverá solo el rango de índices válidos para el array.
1 |
val numbers1 = intArrayOf(1,2,3,4,5) |
2 |
for (index in numbers1.indices) { |
3 |
print("$index index value is ${numbers1[index]}\n") |
4 |
}
|
El código anterior producirá el mismo resultado que el ejemplo anterior. También puedes ver aquí que podemos usar el índice para acceder a un elemento del array, de manera similar a otros lenguajes de programación como Java.
3. Condicionales
Kotlin tiene tres tipos de sentencias de condicionales - las sentencias if, if..else y when.
La sentencia if
Una sentencia if ejecuta algún código si una condición es verdadera, o simplemente la omite, si la condición es falsa. No hay nada especial aquí, Las sentencias if funcionan de manera similar a como lo hacen en la mayoría de los otros lenguajes de programación, incluido Java.
1 |
val number = 20 |
2 |
if (number % 2 == 0) { |
3 |
print("$number is divisible by 2") // 20 is divisible by 2 |
4 |
}
|
También podemos verificar si una variable es de un tipo particular usando la palabra clave is.
1 |
if (number is Int) { |
2 |
print("$number is an integer") |
3 |
}
|
La sentencia if..else
if..else realiza una acción si la condición es verdadera y realiza una acción diferente si la condición es falsa.
1 |
val number = 13 |
2 |
if (number % 2 == 0) { |
3 |
print("$number is divisible by 2") |
4 |
} else { |
5 |
print("$number is not divisible by 2") // 13 is not divisible by 2 |
6 |
}
|
Una característica importante que distingue la sentencia if..else en Kotlin de otros lenguajes de programación como Java, es la capacidad de asignar a una variable el valor devuelto por la instrucción if..else. Esto es posible porque una sentencia if..else puede usarse no solo como una sentencia, sino también como una expresión en Kotlin.
1 |
val number = 13 |
2 |
val result = if (number % 2 == 0) { |
3 |
"$number is divisible by 2"
|
4 |
} else { |
5 |
"$number is not divisible by 2"
|
6 |
}
|
7 |
print(result) // 13 is not divisible by 2 |
En el código anterior, asignamos la variable result con un objeto String basado en la condición de la sentencia if..else. Ten en cuenta que esto devolverá solo la última sentencia en un bloque de condición particular y también que no puede usar un if sin un else como expresión.
1 |
val result = if (number % 2 == 0) { |
2 |
"Divisible by 2"
|
3 |
"Number is $number" // only this string is returned if executed |
4 |
} else { |
5 |
"Not divisible by 2"
|
6 |
"Number is $number"
|
7 |
}
|
La sentencia when
Kotlin introdujo la construcción when como un reemplazo de la conocida sentencia switch que tenemos en diferentes lenguajes de programación como C++, Java y así sucesivamente. when es más concisa y tiene características más poderosas que la sentencia switch con la que podrías estar familiarizado
La sentencia when realiza diferentes acciones en función de los posibles valores de una constante de tipo Int, String, Byte o Short o cualquier otro objeto.
1 |
fun guessTheNumber(number: Int) { |
2 |
|
3 |
when (number) { |
4 |
1 -> println("number is 1") |
5 |
2 -> println("number is 2") |
6 |
3 -> println("number is 3") |
7 |
else -> println("number is neither 1, 2 or 3") |
8 |
}
|
9 |
}
|
En el código anterior, le pasamos a la función guessTheNumber() un parámetro numérico (discutiremos las funciones en Kotlin en una publicación posterior). La expresión when luego verifica si alguna de las ramas coincide con el valor de number y luego ejecuta la acción en esa rama. Si ninguna de las ramas coincide, se ejecuta la rama else.
Otra variante de la expresión when no requiere ningún argumento, como en el ejemplo siguiente.
1 |
fun guessTheNumber(number: Int) { |
2 |
|
3 |
when { |
4 |
number == 1 -> println("number is 1") |
5 |
number == 2 -> println("number is 2") |
6 |
number == 3 -> println("number is 3") |
7 |
else -> println("number is neither 1, 2 or 3") |
8 |
}
|
9 |
}
|
Si queremos ejecutar más de una acción en una rama, necesitamos envolver las acciones entre llaves {}.
1 |
val number = 2 |
2 |
when (number) { |
3 |
1 -> println("number is 1") |
4 |
2 -> { |
5 |
// block of code executed
|
6 |
println("number is 2") |
7 |
println("it is an even number") |
8 |
}
|
9 |
3 -> println("number is 3") |
10 |
}
|
Además, podemos combinar valores de prueba en una sola rama.
1 |
val number = 2 |
2 |
when (number) { |
3 |
1, 2 -> println("number is either 1 or 2") // number is either 1 or 2 |
4 |
3 -> println("number is 3") |
5 |
}
|
Aquí se ejecuta la primera rama porque estamos probando un valor de 1 o 2.
Conclusión
En este tutorial, aprendiste sobre la nulabilidad, los bucles y las condiciones en el lenguaje de programación Kotlin. En el siguiente tutorial de la serie Kotlin desde cero, aprenderás sobre los rangos y la API de colecciones en Kotlin. ¡Nos vemos pronto!
Para obtener más información sobre el lenguaje Kotlin, recomiendo visitar la documentación de Kotlin. ¡O echa un vistazo a algunos de nuestros otros tutoriales de Kotlin aquí en Envato Tuts+!


Android SDKConsejo rápido: escribe un código más limpio con Kotlin SAM ConversionsAshraff Hathibelagal

Android StudioCodificando aplicaciones Android fucionales en Kotlin: ComenzandoJessica Thornsby

Android SDKJava vs.Kotlin: ¿Deberías utilizar Kotlin para el desarrollo de Android?Jessica Thornsby



