Historia de la pregunta:
El operador Elvis (?:) apareció en Kotlin como una forma concisa y segura de manejar valores anulables. Su nombre proviene de la similitud con el peinado de Elvis Presley al mirar el operador de lado. El objetivo es deshacerse del código repetitivo como if (a != null) a else b y hacer que el desarrollo diario sea más conveniente.
Problema:
Acceder directamente a un valor que puede ser nulo provoca un error de tiempo de ejecución (NullPointerException). Por lo tanto, se necesita una herramienta que permita insertar elegantemente valores predeterminados cuando la variable resulta ser nula.
Solución:
El operador Elvis se aplica a tipos anulables. Si la expresión a la izquierda del operador no es nula, se devuelve; de lo contrario, se devuelve la expresión a la derecha. Esto hace que el código sea más compacto y seguro.
Ejemplo de código:
fun getLength(str: String?): Int { return str?.length ?: 0 } val result = getLength(null) // result == 0 val result2 = getLength("Hello") // result2 == 5
Características clave:
¿Qué sucede si hay una expresión con un efecto secundario a la derecha del operador Elvis? ¿Se ejecuta siempre?
¡No! La expresión a la derecha se evalúa solo si a la izquierda resulta ser nula. Esto puede jugar un papel importante si la función tiene efectos secundarios o cálculos "costosos".
Ejemplo de código:
var called = false val x: String? = "test" val y = x ?: run { called = true; "default" } // called será igual a false porque run ni siquiera se ejecutará
¿Se puede usar el operador Elvis para lanzar excepciones?
Sí, en Kotlin se puede escribir así:
fun getLengthStrict(str: String?): Int = str?.length ?: throw IllegalArgumentException("str is null")
Si str es nulo, se lanzará una excepción. Este es un mecanismo conveniente de validación de datos.
¿Se pueden "encadenar" varios operadores Elvis consecutivos?
Sí, este es un enfoque común para las alternativas:
val name = fromDatabase ?: fromCache ?: "Unknown"
Esta expresión devolverá el primer valor NO nulo o la cadena "Unknown".
Anidamiento multinivel de comprobaciones nulas a través de Elvis:
val title = a?.b?.c?.d?.e ?: defaultTitle
Pros:
Contras:
Descomposición explícita por pasos, nombres de variables claros:
val deepValue = a?.b val deeperValue = deepValue?.c?.d ?: default
Pros:
Contras: