¿Debería usar doble =
o triple =
?
if(a === null) {
//do something
}
o
if(a == null) {
//do something
}
De manera similar para 'no es igual a':
if(a !== null) {
//do something
}
o
if(a != null) {
//do something
}
¿Debería usar doble =
o triple =
?
if(a === null) {
//do something
}
o
if(a == null) {
//do something
}
De manera similar para 'no es igual a':
if(a !== null) {
//do something
}
o
if(a != null) {
//do something
}
Respuestas:
Ambos enfoques generan el mismo código de bytes para que pueda elegir lo que prefiera.
Una igualdad estructural a == b
se traduce en
a?.equals(b) ?: (b === null)
Por tanto, al comparar con null
, la igualdad estructural a == null
se traduce en una igualdad referencial a === null
.
De acuerdo con los documentos , no tiene sentido optimizar su código, por lo que puede usar a == null
y tenga en a != null
cuenta que si la variable es una propiedad mutable, no podrá convertirla de manera inteligente en su tipo no anulable dentro de la if
declaración (porque el valor podría haber sido modificado por otro hilo) y tendría que usar el operador de llamada segura con en su let
lugar.
Operador de llamada segura ?.
a?.let {
// not null do something
println(it)
println("not null")
}
Puede usarlo en combinación con el operador de Elvis.
Operador de Elvis ?:
(supongo que porque la marca de interrogación se parece al cabello de Elvis)
a ?: println("null")
Y si quieres ejecutar un bloque de código
a ?: run {
println("null")
println("The King has left the building")
}
Combinando los dos
a?.let {
println("not null")
println("Wop-bop-a-loom-a-boom-bam-boom")
} ?: run {
println("null")
println("When things go null, don't go with them")
}
if
para cheques nulos? a?.let{} ?: run{}
solo es apropiado en casos raros, de lo contrario no es idiomático
null
cheques, estaba enumerando otras opciones viables. Aunque no estoy seguro de si run
tiene algún tipo de penalización de rendimiento. Actualizaré mi respuesta para que quede más claro.
a
es un var
, entonces use la a?.let{} ?: run{}
garantía de que se vinculará correctamente en let
todo el alcance. Si a
es a val
, entonces no hay diferencia.
val
, entonces usar let es diferente y es malo. Encontré este artículo muy bueno para explicarlo - Kotlin: No use LET para la verificación nula .
Operación de acceso seguro
val dialog : Dialog? = Dialog()
dialog?.dismiss() // if the dialog will be null,the dismiss call will be omitted
Dejar funcionar
user?.let {
//Work with non-null user
handleNonNullUser(user)
}
Salida anticipada
fun handleUser(user : User?) {
user ?: return //exit the function if user is null
//Now the compiler knows user is non-null
}
Sombras inmutables
var user : User? = null
fun handleUser() {
val user = user ?: return //Return if null, otherwise create immutable shadow
//Work with a local, non-null variable named user
}
Valor por defecto
fun getUserName(): String {
//If our nullable reference is not null, use it, otherwise use non-null value
return userName ?: "Anonymous"
}
Usa val en lugar de var
val
es de solo lectura, var
es mutable. Se recomienda utilizar tantas propiedades de solo lectura como sea posible, ya que son seguras para subprocesos.
Utilice lateinit
A veces no puedes usar propiedades inmutables. Por ejemplo, sucede en Android cuando alguna propiedad se inicializa en onCreate()
call. Para estas situaciones, Kotlin tiene una función de idioma llamada lateinit
.
private lateinit var mAdapter: RecyclerAdapter<Transaction>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mAdapter = RecyclerAdapter(R.layout.item_transaction)
}
fun updateTransactions() {
mAdapter.notifyDataSetChanged()
}
Además de @Benito Bertoli,
la combinación es realmente diferente a if-else
"test" ?. let {
println ( "1. it=$it" )
} ?: let {
println ( "2. it is null!" )
}
El resultado es:
1. it=test
Pero si:
"test" ?. let {
println ( "1. it=$it" )
null // finally returns null
} ?: let {
println ( "2. it is null!" )
}
El resultado es:
1. it=test
2. it is null!
Además, si usa elvis primero:
null ?: let {
println ( "1. it is null!" )
} ?. let {
println ( "2. it=$it" )
}
El resultado es:
1. it is null!
2. it=kotlin.Unit
Compruebe los métodos útiles, podría ser útil:
/**
* Performs [R] when [T] is not null. Block [R] will have context of [T]
*/
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
return input?.let(callback)
}
/**
* Checking if [T] is not `null` and if its function completes or satisfies to some condition.
*/
inline fun <T: Any> T?.isNotNullAndSatisfies(check: T.() -> Boolean?): Boolean{
return ifNotNull(this) { it.run(check) } ?: false
}
A continuación se muestra un posible ejemplo de cómo utilizar esas funciones:
var s: String? = null
// ...
if (s.isNotNullAndSatisfies{ isEmpty() }{
// do something
}