No puedo entender qué ?:
hace, por ejemplo, en este caso.
val list = mutableList ?: mutableListOf()
y por qué se puede modificar a esto
val list = if (mutableList != null) mutableList else mutableListOf()
No puedo entender qué ?:
hace, por ejemplo, en este caso.
val list = mutableList ?: mutableListOf()
y por qué se puede modificar a esto
val list = if (mutableList != null) mutableList else mutableListOf()
Respuestas:
TL; DR: Si la referencia del objeto resultante [primer operando] no null
lo es, se devuelve. De lo contrario, null
se devuelve el valor del segundo operando (que puede ser )
El operador de Elvis es parte de muchos lenguajes de programación, por ejemplo, Kotlin pero también Groovy o C #. Encuentro la definición de Wikipedia bastante precisa:
En ciertos lenguajes de programación de computadoras, el operador de Elvis
?:
es un operador binario que devuelve su primer operando si ese operando estrue
, y de lo contrario evalúa y devuelve su segundo operando. Se trata de una variante del operador condicional ternario ,? :
encontró en esos idiomas (y muchos otros): el operador Elvis es el operador ternario con su segundo operando omitido .
Lo siguiente es especialmente cierto para Kotlin:
Algunos lenguajes de programación de computadoras tienen una semántica diferente para este operador. En lugar de que el primer operando tenga que dar como resultado un booleano, debe dar como resultado una referencia de objeto . Si la referencia del objeto resultante no
null
lo es, se devuelve. De lo contrario,null
se devuelve el valor del segundo operando (que puede ser ).
Un ejemplo:
x ?: y // yields `x` if `x` is not null, `y` otherwise.
elvis operator
pudiera reducirse más a otra cosa. ¡bonito! Y bonita explicación, ¡gracias!
El operador de Elvis está representado por un signo de interrogación seguido de dos puntos: ?:
y se puede usar con esta sintaxis:
first operand ?: second operand
Le permite escribir un código coherente y funciona como tal:
Si first operand
no es nulo , se devolverá. Si es nulo , second operand
se devolverá. Esto se puede usar para garantizar que una expresión no devuelva un valor nulo, ya que proporcionará un valor que no acepta valores NULL si el valor proporcionado es nulo.
Por ejemplo (en Kotlin):
fun retrieveString(): String { //Notice that this type isn't nullable
val nullableVariable: String? = getPotentialNull() //This variable may be null
return nullableVariable ?: "Secondary Not-Null String"
}
En este caso, si el valor calculado de getPotentialNull
no es nulo, será devuelto por retrieveString
; Si es nulo, "Secondary Not-Null String"
se devolverá la segunda expresión .
También tenga en cuenta que la expresión del lado derecho se evalúa solo si el lado izquierdo es nulo .
En Kotlin, puede usar cualquier expresión como second operand
, por ejemplo, una throw Exception
expresión
return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")
El nombre Elvis Operator proviene del famoso cantante estadounidense Elvis Presley . Su peinado se asemeja a un signo de interrogación.
Fuente: Wojda, I. Moskala, M. Desarrollo de Android con Kotlin. 2017. Packt Publishing
Esto se llama operador de Elvis y lo hace ... Exactamente lo que ha descrito en su pregunta. Si su lado izquierdo es un null
valor, devuelve el lado derecho en su lugar, una especie de retroceso. De lo contrario, solo devuelve el valor en el lado izquierdo.
a ?: b
es solo una abreviatura de if (a != null) a else b
.
Algunos ejemplos más con tipos:
val x: String? = "foo"
val y: String = x ?: "bar" // "foo", because x was non-null
val a: String? = null
val b: String = a ?: "bar" // "bar", because a was null
a != null ? a : b
Echemos un vistazo a la definición :
Cuando tenemos una referencia r anulable, podemos decir "si r no es nulo, utilícelo, de lo contrario use algún valor no nulo x":
los ?:
operador (Elvis) evita la verbosidad y hace que su código sea realmente conciso.
Por ejemplo, muchas funciones de extensión de colección regresan null
como reserva.
listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")
?:
le brinda una forma de manejar el caso de respaldo de manera elegante incluso si tiene varias capas de respaldo. Si es así, simplemente puede encadenar operadores de Elvis multiplicados, como aquí:
val l = listOf(1, 2, 3)
val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")
Si expresara lo mismo con si de lo contrario, sería mucho más código que es más difícil de leer.
Simplemente podemos decir que tienes dos manos. Quieres saber si tu mano izquierda está funcionando en este momento ?. Si la mano izquierda no funciona, de lo return
empty
contrariobusy
Ejemplo para Java:
private int a;
if(a != null){
println("a is not null, Value is: "+a)
}
else{
println("a is null")
}
Ejemplo de Kotlin:
val a : Int = 5
val l : Int = if (a != null) a.length else "a is null"
Básicamente, si el lado izquierdo de Elvis devuelve nulo por alguna razón, devuelve el lado derecho en su lugar.
es decir
val number: Int? = null
println(number ?: "Number is null")
Entonces, si el número NO es nulo , imprimirá el número; de lo contrario , imprimirá "El número es nulo".
El operador de elvis en Kotlin se utiliza para una seguridad nula.
x = a ?: b
En el código anterior, x
se le asignará el valor de a
si a no es null
y b
si a
es null
.
El código de kotlin equivalente sin usar el operador de elvis está a continuación:
x = if(a == null) b else a