1. Antes de comenzar
En este codelab, aprenderás sobre la nulabilidad y la importancia de la seguridad null
. La nulabilidad es un concepto que se suele encontrar en muchos lenguajes de programación. Se refiere a la capacidad de las variables de tener una ausencia de valor. En Kotlin, la nulabilidad se trata de forma intencional para lograr la seguridad de null
.
Requisitos previos
- Conocimiento de los conceptos básicos de programación de Kotlin, incluidas las variables, el acceso a métodos y las propiedades desde una variable y las funciones
println()
ymain()
- Conocimientos de condicionales de Kotlin, incluidas las sentencias
if/else
y las expresiones booleanas
Qué aprenderás
- ¿Qué es
null
? - La diferencia entre los tipos que admiten valores anulables y no anulables
- Qué es la seguridad de
null
, su importancia y cómo Kotlin logra la seguridad denull
- Cómo acceder a los métodos y las propiedades de las variables anulables con el operador de llamada segura
?.
y el operador de aserción no nulo!!
- Cómo realizar comprobaciones de
null
con condicionalesif/else
- Cómo convertir una variable anulable en un tipo no anulable con expresiones
if/else
- Cómo proporcionar un valor predeterminado cuando una variable anulable es
null
con la expresiónif/else
o el operador Elvis?:
Requisitos
- Un navegador web con acceso a Playground de Kotlin
2. Usa variables anulables
¿Qué es null
?
En la Unidad 1, aprendiste que, cuando declaras una variable, debes asignarle un valor de inmediato. Por ejemplo, cuando declaras una variable favoriteActor
, puedes asignarle inmediatamente un valor de string "Sandra Oh"
.
val favoriteActor = "Sandra Oh"
Sin embargo, ¿qué pasa si no tienes un actor favorito? Te recomendamos que asignes un valor "Nobody"
o "None"
a la variable. Este no es un buen enfoque porque tu programa interpreta que la variable favoriteActor
tiene un valor "Nobody"
o "None"
en lugar de no mostrar ningún valor. En Kotlin, puedes usar null
para indicar que no hay un valor asociado a la variable.
Para usar null
en el código, sigue estos pasos:
- En el Playground de Kotlin, reemplaza el contenido en el cuerpo de la función
main()
por una variablefavoriteActor
establecida ennull
:
fun main() {
val favoriteActor = null
}
- Imprime el valor de la variable
favoriteActor
con la funciónprintln()
y ejecuta este programa:
fun main() {
val favoriteActor = null
println(favoriteActor)
}
El resultado se ve como este fragmento de código:
null
Reasignaciones de variables con null
Anteriormente, aprendiste que puedes reasignar variables definidas con la palabra clave var
a diferentes valores del mismo tipo. Por ejemplo, puedes volver a asignar una variable name
declarada con un nombre a otro, siempre que el nuevo nombre sea del tipo String
.
var favoriteActor: String = "Sandra Oh"
favoriteActor = "Meryl Streep"
Hay ocasiones en las que puedes declarar una variable cuando quieras asignarla a null
. Por ejemplo, después de declarar a tu actor favorito, no decides revelarlo. En este caso, es útil asignar la variable favoriteActor
a null
.
Información sobre variables anulables y no anulables
Para reasignar la variable favoriteActor
a null
, sigue estos pasos:
- Cambia la palabra clave
val
porvar
y, luego, especifica que la variablefavoriteActor
sea un tipoString
y asígnala al nombre de tu actor favorito:
fun main() {
var favoriteActor: String = "Sandra Oh"
println(favoriteActor)
}
- Quita la función
println()
:
fun main() {
var favoriteActor: String = "Sandra Oh"
}
- Reasigna la variable
favoriteActor
anull
y ejecuta este programa:
fun main() {
var favoriteActor: String = "Sandra Oh"
favoriteActor = null
}
Recibirás el siguiente mensaje de error:
En Kotlin, hay una distinción entre tipos anulables y no anulables:
- Los tipos anulables son variables que pueden contener
null
. - Los tipos no nulos son variables que no pueden contener
null
.
Un tipo solo es anulable si permites explícitamente que retenga null
. Como se indica en el mensaje de error, el tipo de datos String
es no anulable, por lo que no puedes reasignar la variable a null
.
Para declarar variables anulables en Kotlin, debes agregar un operador ?
al final del tipo. Por ejemplo, un tipo String?
puede contener una string o null
, mientras que un tipo String
solo puede contener una string. Para declarar una variable anulable, debes agregar explícitamente el tipo anulable. Sin el tipo anulable, el compilador de Kotlin infiere que es un tipo no anulable.
- Cambia el tipo de variable
favoriteActor
de un tipo de datosString
a un tipoString?
:
fun main() {
var favoriteActor: String? = "Sandra Oh"
favoriteActor = null
}
- Imprime la variable
favoriteActor
antes y después de la reasignaciónnull
y, luego, ejecuta este programa:
fun main() {
var favoriteActor: String? = "Sandra Oh"
println(favoriteActor)
favoriteActor = null
println(favoriteActor)
}
El resultado se ve como este fragmento de código:
Sandra Oh null
La variable favoriteActor
contenía originalmente una string y, luego, se convirtió en null
.
Pruébalo
Ahora que puedes usar el tipo anulable String?
, ¿puedes inicializar una variable con un valor Int
y reasignarla a null
?
Escribe un valor Int
anulable
- Quita todo el código de la función
main()
:
fun main() {
}
- Crea una variable
number
de un tipoInt
anulable y asígnale un valor10
:
fun main() {
var number: Int? = 10
}
- Imprime la variable
number
y ejecuta este programa:
fun main() {
var number: Int? = 10
println(number)
}
El resultado es el esperado:
10
- Reasigna la variable
number
anull
para confirmar que la variable sea anulable:
fun main() {
var number: Int? = 10
println(number)
number = null
}
- Agrega otra sentencia
println(number)
como línea final del programa y, luego, ejecútalo:
fun main() {
var number: Int? = 10
println(number)
number = null
println(number)
}
El resultado es el esperado:
10 null
3. Procesa variables anulables
Anteriormente, aprendiste a usar el operador .
para acceder a propiedades y métodos de variables no anulables. En esta sección, aprenderás a usarlo para acceder a métodos y propiedades de variables anulables.
Para acceder a una propiedad de la variable favoriteActor
no anulable, sigue estos pasos:
- Quita todo el código de la función
main()
y, luego, declara una variablefavoriteActor
de tipoString
y asígnala al nombre de tu actor favorito:
fun main() {
var favoriteActor: String = "Sandra Oh"
}
- Imprime la cantidad de caracteres en el valor de la variable
favoriteActor
con la propiedadlength
y, luego, ejecuta este programa:
fun main() {
var favoriteActor: String = "Sandra Oh"
println(favoriteActor.length)
}
El resultado es el esperado:
9
Hay nueve caracteres en el valor de la variable favoriteActor
, incluidos los espacios. Es posible que la cantidad de caracteres del nombre de tu actor favorito sea diferente.
Cómo acceder a una propiedad de una variable anulable
Imagina que deseas que la variable favoriteActor
sea anulable, de manera que las personas que no tengan un actor favorito puedan asignarla a null
.
Para acceder a una propiedad de la variable favoriteActor
anulable, sigue estos pasos:
- Cambia el tipo de variable
favoriteActor
a uno anulable y, luego, ejecuta este programa:
fun main() {
var favoriteActor: String? = "Sandra Oh"
println(favoriteActor.length)
}
Recibirás el siguiente mensaje de error:
Este es un error de compilación. Como se mencionó en un codelab anterior, un error de compilación se produce cuando Kotlin no puede compilar el código debido a un error de sintaxis en tu código.
Kotlin aplica reglas sintácticas de forma intencional para lograr la seguridad de null
, que hace referencia a una garantía de que no se realizarán llamadas accidentales en variables null
. Esto no significa que las variables no pueden ser null
. Significa que, si se accede a un miembro de una variable, la variable no puede ser null
.
Esto es fundamental porque, si se intenta acceder a un miembro de una variable null
( conocido referencia null
) durante la ejecución de una app, esta fallará porque la variable null
no contiene ninguna propiedad ni método. Este tipo de falla se conoce como error de tiempo de ejecución, ya que el error ocurre después de que se compila y se ejecuta el código.
Debido a la naturaleza de seguridad de null
de Kotlin, se evitan esos errores de tiempo de ejecución porque el compilador de Kotlin fuerza una verificación de null
para tipos anulables. La verificación Null
hace referencia a un proceso en el que se verifica si una variable podría ser null
antes de que se acceda a ella y se la trate como un tipo no anulable. Si deseas usar un valor anulable como su tipo no anulable, debes realizar una verificación de null
de forma explícita. Obtén más información al respecto en la sección Cómo usarcondicionales if/else
que se encuentra más adelante en este codelab.
En este ejemplo, el código falla en el tiempo de compilación porque no se permite la referencia directa a la propiedad length
para la variable favoriteActor
debido a que existe la posibilidad de que la variable sea null
.
A continuación, aprenderás diversas técnicas y operadores para trabajar con tipos anulables.
Usa el operador de llamada segura ?.
.
Puedes usar el operador de llamada segura ?.
para acceder a métodos o propiedades de variables anulables.
Para usar el operador de llamada segura ?.
a fin de acceder a un método o una propiedad, agrega un símbolo ?
después del nombre de la variable y accede al método o a la propiedad con la notación .
.
El operador de llamada segura ?.
permite un acceso más seguro a las variables anulables, ya que el compilador de Kotlin detiene cualquier intento de acceso del miembro a las referencias null
y muestra null
para el miembro al que se accede.
Para acceder de manera segura a una propiedad de la variable favoriteActor
anulable, sigue estos pasos:
- En la sentencia
println()
, reemplaza el operador.
por el operador de llamada segura?.
:
fun main() {
var favoriteActor: String? = "Sandra Oh"
println(favoriteActor?.length)
}
- Ejecuta este programa y, luego, verifica que el resultado sea el esperado:
9
Es posible que la cantidad de caracteres del nombre de tu actor favorito sea diferente.
- Reasigna la variable
favoriteActor
anull
y ejecuta este programa:
fun main() {
var favoriteActor: String? = null
println(favoriteActor?.length)
}
Verás el siguiente resultado:
null
Ten en cuenta que el programa no falla incluso en caso de intento de acceso a la propiedad length
de una variable null
. La expresión de llamada segura simplemente muestra null
.
Usa el operador de aserción no nulo de !!
También puedes usar el operador de aserción !!
no nulo para acceder a métodos o propiedades de variables anulables.
Después de la variable anulable, debes agregar el operador de aserción !!
no nulo seguido del operador .
y, luego, el método o la propiedad sin espacios.
Como sugiere el nombre, si usas la aserción no nula !!
, significa que confirmas que el valor de la variable no es null
, sin importar si lo es o no.
A diferencia de los operadores de llamada segura ?.
, el uso de un operador de aserción no nulo de !!
puede generar un error NullPointerException
si la variable anulable es realmente null
. Por lo tanto, debe hacerse solo cuando la variable siempre es no anulable o si se estableció un adecuado manejo de excepción. Si no se controlan, las excepciones causan errores de tiempo de ejecución. Aprenderás sobre el manejo de excepciones en unidades posteriores de este curso.
Para acceder a una propiedad de la variable favoriteActor
con el operador de aserción no nulo de !!
, sigue estos pasos:
- Reasigna la variable
favoriteActor
al nombre de tu actor favorito y, luego, reemplaza el operador de llamada segura?.
por el operador de aserción no nulo!!
en la sentenciaprintln()
:
fun main() {
var favoriteActor: String? = "Sandra Oh"
println(favoriteActor!!.length)
}
- Ejecuta este programa y, luego, verifica que el resultado sea el esperado:
9
Es posible que la cantidad de caracteres del nombre de tu actor favorito sea diferente.
- Reasigna la variable
favoriteActor
anull
y ejecuta este programa:
fun main() {
var favoriteActor: String? = null
println(favoriteActor!!.length)
}
Recibes un error NullPointerException
:
Este error de Kotlin muestra que tu programa falló durante la ejecución. Por lo tanto, no se recomienda usar el operador de aserción no nulo !!
, a menos que sepas con seguridad que la variable no es null
.
Usa los condicionales if/else
Puedes usar la rama if
en los condicionales if/else
para realizar verificaciones null
.
Para realizar verificaciones de null
, puedes revisar que la variable anulable no sea igual a null
con el operador de comparación !=
.
Sentencias if/else
Se puede usar una sentencia if/else
junto con una verificación null
de la siguiente manera:
La verificación de null es útil cuando se combina con una sentencia if/else
:
- La verificación de
null
de la expresiónnullableVariable != null
se usa como la condiciónif
. - Body 1 dentro de la rama
if
supone que la variable no es anulable. Por lo tanto, en este cuerpo, puedes acceder libremente a los métodos o las propiedades de la variable como si fuera no anulable sin usar un operador de llamada segura?.
o un operador de aserción no nulo de!!
. - El body 2 dentro de la rama
else
supone que la variable esnull
. Por lo tanto, en este cuerpo, puedes agregar sentencias que deberían ejecutarse cuando la variable esnull
. La ramaelse
es opcional. Solo puedes usar el condicionalif
para ejecutar una verificación denull
sin proporcionar una acción predeterminada cuando falla la verificación denull
.
La verificación de null
es más conveniente para usar con la condición if
cuando hay varias líneas de código que usan la variable anulable. Por el contrario, el operador de llamada segura ?.
es más conveniente para una sola referencia de la variable anulable.
A fin de escribir una sentencia if/else
con una verificación de null
para la variable favoriteActor
, sigue estos pasos:
- Vuelve a asignar la variable
favoriteActor
al nombre de tu actor favorito y, luego, quita la sentenciaprintln()
:
fun main() {
var favoriteActor: String? = "Sandra Oh"
}
- Agrega una rama
if
con una condiciónfavoriteActor != null
:
fun main() {
var favoriteActor: String? = "Sandra Oh"
if (favoriteActor != null) {
}
}
- En el cuerpo de la rama
if
, agrega una sentenciaprintln
que acepte una string"The number of characters in your favorite actor's name is ${favoriteActor.length}"
y, luego, ejecuta este programa:
fun main() {
var favoriteActor: String? = "Sandra Oh"
if (favoriteActor != null) {
println("The number of characters in your favorite actor's name is ${favoriteActor.length}.")
}
}
El resultado es el esperado.
The number of characters in your favorite actor's name is 9.
Es posible que la cantidad de caracteres del nombre de tu actor favorito sea diferente.
Ten en cuenta que puedes acceder al método de longitud del nombre directamente con el operador .
porque accedes al método length
dentro de la rama if
después de la verificación de null
. Como tal, el compilador de Kotlin sabe que no hay posibilidad de que la variable favoriteActor
sea null
, por lo que permite el acceso directo a la propiedad.
- Opcional: Agrega una rama
else
para controlar una situación en la que el nombre del actor seanull
:
fun main() {
var favoriteActor: String? = "Sandra Oh"
if (favoriteActor != null) {
println("The number of characters in your favorite actor's name is ${favoriteActor.length}.")
} else {
}
}
- En el cuerpo de la rama
else
, agrega una sentenciaprintln
que tome una string"You didn't input a name."
:
fun main() {
var favoriteActor: String? = "Sandra Oh"
if (favoriteActor != null) {
println("The number of characters in your favorite actor's name is ${favoriteActor.length}.")
} else {
println("You didn't input a name.")
}
}
- Asigna la variable
favoriteActor
anull
y ejecuta este programa:
fun main() {
var favoriteActor: String? = null
if(favoriteActor != null) {
println("The number of characters in your favorite actor's name is ${favoriteActor.length}.")
} else {
println("You didn't input a name.")
}
}
El resultado es el esperado:
You didn't input a name.
Expresiones if/else
También puedes combinar la verificación de null
con una expresión if/else
a fin de convertir una variable anulable en una variable no anulable.
Para asignar una expresión if/else
a un tipo no anulable, sigue estos pasos:
- La verificación de
null
nullableVariable != null
se usa como la condiciónif
. - Body 1 dentro de la rama
if
supone que la variable no es anulable. Por lo tanto, en este body, puedes acceder a métodos o propiedades de la variable como si fuera una variable no anulable sin un operador seguro?.
ni un operador de aserción no nulo!!
. - El body 2 dentro de la rama
else
supone que la variable esnull
. Por lo tanto, en este body, puedes agregar sentencias que deberían ejecutarse cuando la variable esnull
. - En la línea final de body 1 y body 2, debes usar una expresión o un valor que de como resultado un tipo no anulable para que se asigne a la variable no anulable cuando la verificación de
null
sea exitosa o falle, respectivamente.
Si deseas usar la expresión if/else
para reescribir el programa a fin de que solo use una sentencia println
, sigue estos pasos:
- Asigna la variable
favoriteActor
al nombre de tu actor favorito:
fun main() {
var favoriteActor: String? = "Sandra Oh"
if (favoriteActor != null) {
println("The number of characters in your favorite actor's name is ${favoriteActor.length}.")
} else {
println("You didn't input a name.")
}
}
- Crea una variable
lengthOfName
y asígnala a la expresiónif/else
:
fun main() {
var favoriteActor: String? = "Sandra Oh"
val lengthOfName = if(favoriteActor != null) {
println("The number of characters in your favorite actor's name is ${favoriteActor.length}.")
} else {
println("You didn't input a name.")
}
}
- Quita ambas sentencias
println()
de las ramasif
yelse
:
fun main() {
var favoriteActor: String? = "Sandra Oh"
val lengthOfName = if(favoriteActor != null) {
} else {
}
}
- En el cuerpo de la rama
if
, agrega una expresiónfavoriteActor.length
:
fun main() {
val favoriteActor: String? = "Sandra Oh"
val lengthOfName = if(favoriteActor != null) {
favoriteActor.length
} else {
}
}
Se puede acceder a la propiedad length
de la variable favoriteActor
directamente con el operador .
.
- En el cuerpo de la rama
else
, agrega un valor0
:
fun main() {
val favoriteActor: String? = "Sandra Oh"
val lengthOfName = if(favoriteActor != null) {
favoriteActor.length
} else {
0
}
}
El valor 0
actúa como predeterminado cuando el nombre es null
.
- Al final de la función
main()
, agrega una sentenciaprintln
que tome una string"The number of characters in your favorite actor's name is $lengthOfName."
y ejecuta este programa:
fun main() {
val favoriteActor: String? = "Sandra Oh"
val lengthOfName = if(favoriteActor != null) {
favoriteActor.length
} else {
0
}
println("The number of characters in your favorite actor's name is $lengthOfName.")
}
El resultado es el esperado:
The number of characters in your favorite actor's name is 9.
Puede haber diferencias entre la cantidad de caracteres del nombre que usaste.
Usa el operador Elvis ?:
El operador Elvis ?:
se puede utilizar junto con el operador de llamada segura ?.
. Con el operador Elvis ?:
, puedes agregar un valor predeterminado cuando el operador de llamada segura ?.
muestre null
. Es similar a una expresión if/else
, pero más idiomática.
Si la variable no es null
, se ejecuta la expresión antes que el operador Elvis ?:
. Si la variable es null
, se ejecuta la expresión después del operador Elvis ?:
.
Para modificar el programa anterior a fin de usar el operador Elvis ?:
, sigue estos pasos:
- Quita el condicional
if/else
, establece la variablelengthOfName
en la variablefavoriteActor
anulable y usa el operador de llamada segura?.
para llamar a su propiedadlength
:
fun main() {
val favoriteActor: String? = "Sandra Oh"
val lengthOfName = favoriteActor?.length
println("The number of characters in your favorite actor's name is $lengthOfName.")
}
- Después de la propiedad
length
, agrega el operador Elvis?:
seguido de un valor0
y ejecuta este programa:
fun main() {
val favoriteActor: String? = "Sandra Oh"
val lengthOfName = favoriteActor?.length ?: 0
println("The number of characters in your favorite actor's name is $lengthOfName.")
}
El resultado es el mismo que el del resultado anterior:
The number of characters in your favorite actor's name is 9.
4. Conclusión
¡Felicitaciones! Aprendiste sobre la nulabilidad y cómo usar varios operadores para administrarla.
Resumen
- Se puede establecer una variable en
null
para indicar que no tiene ningún valor. - No se pueden asignar variables no anulables
null
. - Se pueden asignar variables anulables
null
. - Para acceder a los métodos o las propiedades de las variables anulables, debes usar operadores de llamada segura
?.
u operadores de aserción no nulos!!
. - Puedes usar sentencias
if/else
con verificaciones denull
para acceder a variables anulables en contextos no anulables. - Puedes convertir una variable anulable en un tipo no anulable con expresiones
if/else
. - Puedes proporcionar un valor predeterminado cuando una variable anulable sea
null
con la expresiónif/else
o el operador Elvis?:
.