Je n'arrive pas à comprendre ce que ?:
fait par exemple dans ce cas
val list = mutableList ?: mutableListOf()
et pourquoi peut-il être modifié à cette
val list = if (mutableList != null) mutableList else mutableListOf()
TL; DR: si la référence d'objet obtenue [premier opérande] n'est pas null
, elle est renvoyée. Sinon, la valeur du second opérande (qui peut être null
) est renvoyée
Le Elvis operator fait partie de nombreux langages de programmation, par exemple: Kotlin mais aussi Groovy ou C #. Je trouve la définition Wikipedia assez précise:
Dans certains langages de programmation, l'opérateur Opérateur Elvis
?:
est un opérateur binaire qui renvoie son premier opérande si cet opérande esttrue
, et sinon évalue et retourne son deuxième opérande. C'est une variante de l'opérateur conditionnel ternaire,? :
, trouvée dans ces langues (et dans beaucoup d'autres): l'opérateur Elvis est l'opérateur ternaire avec son deuxième opérande omis.
Ce qui suit est particulièrement vrai pour Kotlin:
Certains langages de programmation informatique ont une sémantique différente pour cet opérateur. Au lieu que le premier opérande ait pour résultat un booléen, il doit donner lieu à une référence d'objet . Si la référence d'objet obtenue n'est pas
null
, elle est renvoyée. Sinon, la valeur du deuxième opérande (qui peut êtrenull
) est renvoyée.
Un exemple:
x ?: y // yields `x` if `x` is not null, `y` otherwise.
L’opérateur Elvis est représenté par un point d’interrogation suivi de deux points: ?:
et il peut être utilisé avec cette syntaxe:
_first operand ?: second operand
_
Il vous permet d'écrire un code consise et fonctionne comme tel:
Si _first operand
_ n'est pas null , il sera renvoyé. Si elle est nulle , le _second operand
_ sera renvoyé. Cela peut être utilisé pour garantir qu'une expression ne renverra pas une valeur null, car vous fournirez une valeur non nullable si la valeur fournie est null.
Par exemple (en Kotlin):
_fun retrieveString(): String { //Notice that this type isn't nullable
var nullableVariable: String? = getPotentialNull() //This variable may be null
return nullableVariable ?: "Secondary Not-Null String"
}
_
Dans ce cas, si la valeur calculée de getPotentialNull
n'est pas nulle, elle sera renvoyée par retrieveString
; Si elle est nulle, la deuxième expression _"Secondary Not-Null String"
_ sera retournée à la place.
Notez également que l'expression du côté droit est évaluée uniquement si le côté gauche est null .
En Kotlin, vous pouvez utiliser n’importe quelle expression sous la forme _second operand
_, telle qu’une expression _throw Exception
_.
_return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")
_
Le nom Elvis Operator vient du célèbre chanteur américain Elvis Presley . Sa coiffure ressemble à un point d'interrogation
Source: Wojda, I. Moskala, M. Android Développement avec Kotlin. 2017. Packt Publishing
C'est ce qu'on appelle le opérateur Elvis et c'est ce que vous faites ... Exactement ce que vous avez décrit dans votre question. Si son côté gauche est une valeur null
, il renvoie plutôt le côté droit, en quelque sorte comme un repli. Sinon, il ne fait que renvoyer la valeur sur le côté gauche.
a ?: b
est simplement un raccourci pour if (a != null) a else b
.
Quelques exemples supplémentaires avec des types:
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
Jetons un coup d'oeil à la définition :
Lorsque nous avons une référence rable n, nous pouvons dire "si r n'est pas nul, utilisez-le, sinon utilisez une valeur x non nulle":
L'opérateur ?:
(Elvis) évite la verbosité et rend votre code très concis.
Par exemple, de nombreuses fonctions d'extension de collection renvoient null
comme solution de secours.
listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")
?:
vous permet de gérer le cas de repli de façon élégante même si vous avez plusieurs couches de repli. Si c'est le cas, vous pouvez simplement chaîner plusieurs opérateurs Elvis, comme ici:
val l = listOf(1, 2, 3)
val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")
Si vous exprimiez la même chose avec sinon, ce serait beaucoup plus de code, ce qui est plus difficile à lire.
Fondamentalement, si le côté gauche d’Elvis renvoie la valeur null pour une raison quelconque, renvoie le côté droit.
c'est à dire.
val number: Int? = null
println(number ?: "Number is null")
Alors, si nombre n'est PAS nul, il imprimera le numéro, autrement affichera "Le nombre est nul".
Nous pouvons simplement dire que vous avez deux mains. Vous voulez savoir si votre main gauche fonctionne maintenant? Si la main gauche ne fonctionne pas, return
empty
sinon busy
Exemple pour Java:
private int a;
if(a != null){
println("a is not null, Value is: "+a)
}
else{
println("a is null")
}
Exemple pour Kotlin:
val a : Int = 5
val l : Int = if (a != null) a.length else "a is null"