Devrais-je utiliser double =
ou triple =
?
if(a === null) {
//do something
}
ou
if(a == null) {
//do something
}
De même pour 'pas égal':
if(a !== null) {
//do something
}
ou
if(a != null) {
//do something
}
Les deux approches génèrent le même bytecode afin que vous puissiez choisir ce que vous préférez.
Une égalité structurelle a == b
est traduite en
a?.equals(b) ?: (b === null)
Par conséquent, en comparant à null
, l'égalité structurelle a == null
est traduite en une égalité référentielle a === null
.
Selon les docs , il n’ya aucun intérêt à optimiser votre code, vous pouvez donc utiliser a == null
et a != null
Remarque que si la variable est une propriété mutable, vous ne pourrez pas l'intégrer intelligemment à son type non nullable dans l'instruction if
(car la valeur pourrait avoir été modifiée par un autre thread) et vous devriez plutôt utiliser l'opérateur d'appel sûr avec let
.
Opérateur appelant?.
a?.let {
// not null do something
println(it)
println("not null")
}
Vous pouvez l’utiliser en combinaison avec l’opérateur Elvis.
Opérateur Elvis ?:
_ (Je suppose que le point d'interrogation ressemble aux cheveux d'Elvis))}
a ?: println("null")
Et si vous voulez exécuter un bloc de code
a ?: run {
println("null")
println("The King has left the building")
}
Combinant les deux
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")
}
Laisse la fonction
user?.let {
//Work with non-null user
handleNonNullUser(user)
}
Sortie anticipée
fun handleUser(user : User?) {
user ?: return //exit the function if user is null
//Now the compiler knows user is non-null
}
Ombres immuables
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
}
Valeur par défaut
fun getUserName(): String {
//If our nullable reference is not null, use it, otherwise use non-null value
return userName ?: "Anonymous"
}
Vérifiez les méthodes utiles, cela pourrait être utile:
/**
* 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
}
Vous trouverez ci-dessous un exemple d'utilisation de ces fonctions:
var s: String? = null
// ...
if (s.isNotNullAndSatisfies{ isEmpty() }{
// do something
}
Ajout à Benito Bertoli,
la combinaison est en réalité contrairement à if-else
"test" ?. let {
println ( "1. it=$it" )
} ?: let {
println ( "2. it is null!" )
}
Le résultat est:
1. it=test
Mais si:
"test" ?. let {
println ( "1. it=$it" )
null // finally returns null
} ?: let {
println ( "2. it is null!" )
}
Le résultat est:
1. it=test
2. it is null!
Aussi, si vous utilisez elvis en premier:
null ?: let {
println ( "1. it is null!" )
} ?. let {
println ( "2. it=$it" )
}
Le résultat est:
1. it is null!
2. it=kotlin.Unit