not - non null kotlin
¿La mejor manera de hacer un cheque nulo en Kotlin? (5)
¿Debo usar double
=
o triple
=
?
if(a === null) {
//do something
}
o
if(a == null) {
//do something
}
Del mismo modo para ''no es igual'':
if(a !== null) {
//do something
}
o
if(a != null) {
//do something
}
Kotlin maneras de manejar nulo
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 temprana
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"
}
Use val en lugar de var
val
es de solo lectura,
var
es mutable.
Se recomienda utilizar tantas propiedades de solo lectura como sea posible, son seguras para subprocesos.
Use lateinit
A veces no puedes usar propiedades inmutables.
Por ejemplo, sucede en Android cuando se inicializa alguna propiedad en la llamada
onCreate()
.
Para estas situaciones, Kotlin tiene una función de lenguaje 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()
}
Adición a @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
Ambos enfoques generan el mismo código de bytes para que pueda elegir lo que prefiera.
Consulte 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 usar esas funciones:
var s: String? = null
// ...
if (s.isNotNullAndSatisfies{ isEmpty() }{
// do something
}
Una igualdad estructural
a == b
se traduce a
a?.equals(b) ?: (b === null)
Por lo tanto, cuando se compara con
null
, la igualdad estructural
a == null
se traduce en una igualdad referencial
a === null
.
Según los
docs
, no tiene sentido optimizar su código, por lo que puede usar
a == null
y
a != null
Tenga en cuenta
que si la variable es una propiedad mutable, no podrá convertirla de manera inteligente a su tipo no anulable dentro de la instrucción
if
(porque el valor podría haber sido modificado por otro hilo) y tendría que usar el operador de llamada segura con
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")
}