¿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
}
kotlin
kotlin-null-safety
pdeva
fuente
fuente
Respuestas:
Ambos enfoques generan el mismo código de bytes para que pueda elegir lo que prefiera.
fuente
Una igualdad estructural
a == b
se traduce ena?.equals(b) ?: (b === null)
Por tanto, al comparar con
null
, la igualdad estructurala == null
se traduce en una igualdad referenciala === null
.De acuerdo con los documentos , no tiene sentido optimizar su código, por lo que puede usar
a == null
y tenga ena != 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 sulet
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") }
fuente
if
para cheques nulos?a?.let{} ?: run{}
solo es apropiado en casos raros, de lo contrario no es idiomáticonull
cheques, estaba enumerando otras opciones viables. Aunque no estoy seguro de sirun
tiene algún tipo de penalización de rendimiento. Actualizaré mi respuesta para que quede más claro.a
es unvar
, entonces use laa?.let{} ?: run{}
garantía de que se vinculará correctamente enlet
todo el alcance. Sia
es aval
, 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 .Maneras de Kotlin de manejar null
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 llamadalateinit
.private lateinit var mAdapter: RecyclerAdapter<Transaction> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mAdapter = RecyclerAdapter(R.layout.item_transaction) } fun updateTransactions() { mAdapter.notifyDataSetChanged() }
fuente
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
fuente
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 }
fuente