Je ne peux pas comprendre ce que ?:
fait dans, par exemple, ce cas:
val list = mutableList ?: mutableListOf()
et pourquoi peut-il être modifié en ceci:
val list = if (mutableList != null) mutableList else mutableListOf()
Je ne peux pas comprendre ce que ?:
fait dans, par exemple, ce cas:
val list = mutableList ?: mutableListOf()
et pourquoi peut-il être modifié en ceci:
val list = if (mutableList != null) mutableList else mutableListOf()
TL;DR: Si la référence d'objet résultante [premier opérande] n'est pas null
, elle est renvoyée. Sinon, la valeur du deuxième opérande (qui peut être null
) est renvoyée. De plus, l'opérateur peut envoyer une exception si null est renvoyé.
L'opérateur Elvis fait partie de nombreux langages de programmation, par exemple Kotlin mais aussi Groovy ou C#. Je trouve la définition de Wikipedia assez précise :
Dans certains langages de programmation informatique, l'opérateur Elvis
?:
est un opérateur binaire qui renvoie son premier opérande si cet opérande esttrue
, et évalue sinon et renvoie son deuxième opérande. C'est une variante de l'opérateur conditionnel ternaire,? :
, trouvé dans ces langages (et 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 des sémantiques différentes pour cet opérateur. Au lieu que le premier opérande doive résulter en un booléen, il doit résulter en une référence d'objet. Si la référence d'objet résultante n'est pas
null
, elle est renvoyée. Sinon, la valeur du deuxième opérande (qui peut êtrenull
) est renvoyée. Si le deuxième opérande est null, l'opérateur peut également envoyer une exception.
Un exemple :
x ?: y // renvoie `x` si `x` n'est pas null, `y` sinon.
x ?: throw SomeException() // renvoie `x` si `x` n'est pas null, envoie SomeException sinon
L'opérateur Elvis est représenté par un point d'interrogation suivi de deux points : ?:
et peut être utilisé avec cette syntaxe :
premier opérande ?: deuxième opérande
Cela vous permet d'écrire un code concis, et fonctionne comme suit :
Si le premier opérande
n'est pas null, alors il sera retourné. S'il est null, alors le deuxième opérande
sera retourné. Cela peut être utilisé pour garantir qu'une expression ne retournera pas de valeur nulle, car vous fournirez une valeur non nullable si la valeur fournie est nulle.
Par exemple (en Kotlin) :
fun retrieveString(): String { //Remarquez que ce type n'est pas nullable
val variableNulle: String? = getPotentialNull() //Cette variable peut être nulle
return variableNulle ?: "Seconde Chaîne Non-Null"
}
Dans ce cas, si la valeur calculée de getPotentialNull
n'est pas nulle, elle sera retournée par retrieveString
; si elle est nulle, la seconde expression "Seconde Chaîne Non-Null"
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 pourriez utiliser n'importe quelle expression en tant que deuxième opérande
, telle qu'une expression throw Exception
return variableNulle ?: throw IllegalResponseException("Ma fonction interne a retourné null ! Oh non !")
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 Development with Kotlin. 2017. Packt Publishing
Cela s'appelle l'opérateur Elvis et il fait... 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, un peu comme une solution de secours. Sinon, il renvoie simplement la valeur du 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", car x était non-nul
val a: String? = null
val b: String = a ?: "bar" // "bar", car a était null
Jetons un coup d'œil à la définition :
Lorsque nous avons une référence nullable r, nous pouvons dire "si r n'est pas null, l'utiliser, sinon utiliser une valeur non nulle x" :
L'opérateur ?:
(Elvis) évite la verbeosité et rend votre code vraiment concis.
Par exemple, de nombreuses fonctions d'extension de collection retournent null
comme valeur de repli.
listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")
?:
vous donne un moyen de gérer élégamment le cas de repli même si vous avez plusieurs niveaux de repli. Si tel 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 deviez exprimer la même chose avec un if else, cela nécessiterait beaucoup plus de code qui serait plus difficile à lire.
En fait, vous avez deux mains. Si votre main gauche ne fonctionne pas, return
empty
sinon busy
Exemple pour Java :
private int a;
if(a != null){
println("a n'est pas nul, sa valeur est: "+a)
}
else{
println("a est nul")
}
Exemple pour Kotlin :
val a : Int = 5
val l : Int = if (a != null) a.length else "a est nul"
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
10 votes
Retournez le côté gauche s'il n'est pas nul, sinon retournez le côté droit. La première expression est une courte notation de la deuxième expression. kotlinlang.org/docs/reference/null-safety.html#elvis-operator