Que fait?: Faire à Kotlin? (Opérateur Elvis)

98

Je ne peux pas comprendre ce que ?:fait par exemple ce cas

val list = mutableList ?: mutableListOf() 

et pourquoi peut-il être modifié en ceci

val list = if (mutableList != null) mutableList else mutableListOf()
Jocas
la source
5
Retourne le côté gauche s'il n'est pas nul, sinon retourne le côté droit. La première expression est une notation courte pour la deuxième expression. kotlinlang.org/docs/reference/null-safety.html#elvis-operator
Eugen Pechanec

Réponses:

115

TL; DR: Si la référence d'objet résultant [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


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 est true, et sinon évalue et retourne son deuxième opérande. Il est une variante de l'opérateur conditionnel ternaire , ? :, trouvé dans ces langues (et bien d' autres): l'opérateur Elvis est l' opérateur ternaire avec son second 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 résulter en une référence d'objet . Si la référence d'objet résultante ne l'est pas null, elle est renvoyée. Sinon, la valeur du deuxième opérande (qui peut être null) est renvoyée.

Un exemple:

x ?: y // yields `x` if `x` is not null, `y` otherwise.
s1m0nw1
la source
3
C'est vraiment cool. Je n'ai jamais pensé elvis operatorpouvoir être réduit à autre chose. agréable! Et belle explication, merci!
sud007
88

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:

S'il first operand n'est pas nul , il sera renvoyé. S'il est nul , le second operandsera retourné. Cela peut être utilisé pour garantir qu'une expression ne retournera pas une valeur nulle, car vous fournirez une valeur non nullable si la valeur fournie est nulle.


Par exemple (à Kotlin):

fun retrieveString(): String {    //Notice that this type isn't nullable
    val nullableVariable: String? = getPotentialNull() //This variable may be null
    
    return nullableVariable ?: "Secondary Not-Null String"
}

Dans ce cas, si la valeur calculée de getPotentialNulln'est pas nulle, elle sera renvoyée par retrieveString; S'il est nul, la deuxième expression "Secondary Not-Null String"sera renvoyée à la place.

Notez également que l'expression du côté droit est évaluée uniquement si le côté gauche est nul .

Dans Kotlin, vous pouvez utiliser n'importe quelle expression second operandtelle qu'une throw Exceptionexpression

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

Elvis QuestionMark

Source: Wojda, I. Moskala, M. Développement Android avec Kotlin. 2017. Packt Publishing

LeoColman
la source
84
Plus 1 pour illustrer M. Presley
s1m0nw1
7
? :) (voyez-le comme Elvis souriant)
LeoColman
1
Après un certain temps, je ne comprends pas pourquoi il s'appelle Elvis Operator. Votre illustration m'a fait savoir pourquoi il s'appelle Elvis Operator. :)
Yohanes AI
est-ce que l'histoire d'Elvis est vraiment vraie? haha
Hillcow
@Kerooker Il ne sourit pas,?: | sera mieux IMO.
ahmed galal
38

C'est ce qu'on appelle l' opérateur Elvis et c'est le cas ... Exactement ce que vous avez décrit dans votre question. Si son côté gauche est une nullvaleur, il renvoie le côté droit à la place, une sorte de repli. Sinon, il renvoie simplement la valeur sur le côté gauche.

a ?: best juste un raccourci pour if (a != null) a else b.

Quelques autres exemples 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
zsmb13
la source
10
si vous venez de java, c'est plus un raccourci pour:a != null ? a : b
crgarridos
9

Jetons un coup d'œil à la définition :

Lorsque nous avons une référence r nullable, 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 vraiment concis.

Par exemple, de nombreuses fonctions d'extension de collection sont nullrenvoyées comme solution de secours.

listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")

?:vous donne un moyen de gérer le cas de secours de manière élégante même si vous avez plusieurs couches de secours. Si tel est le cas, vous pouvez simplement chaîner des opérateurs Elvis multipliés, 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 if else, ce serait beaucoup plus de code qui est plus difficile à lire.

Willi Mentzel
la source
3

Nous pouvons simplement dire que vous avez deux mains. Vous voulez savoir, est-ce que votre main gauche travaille en ce moment ?. Si la main gauche ne fonctionne pas, return emptysinonbusy

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"
Romman
la source
J'adore cette réponse. Trop propre à comprendre.
Gk Mohammad Emon le
2

Fondamentalement, si le côté gauche d'Elvis retourne null pour une raison quelconque, renvoie le côté droit à la place.

c'est à dire

val number: Int? = null
println(number ?: "Number is null")

Donc, si nombre n'est PAS nul , il affichera le nombre, sinon affichera "Le nombre est nul".

pauloaap
la source
1

L'opérateur elvis de Kotlin est utilisé pour la sécurité nulle.

x = a ?: b

Dans le code ci-dessus, xon attribuera la valeur de aif a n'est pas nullet bsi aest null.

Le code kotlin équivalent sans utiliser l'opérateur elvis est ci-dessous:

x = if(a == null) b else a
Abhishek A Udupa
la source
1

Un petit ajout cependant est-ce

X = A ?: B

Xsera toujours nullsi les deux Aet Bévaluer ànull

Par conséquent, si vous voulez Xtoujours être non-null, assurez-vous que Bc'est toujours un non-nullou qui Bévalue toujours non-nulls'il s'agit d'une fonction ou d'une expression.

Wilson
la source