web-dev-qa-db-fra.com

Que fait-on à Kotlin? (Opérateur Elvis)

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()
52
Jocas

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 est true, 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 être null) est renvoyée.

Un exemple:

x ?: y // yields `x` if `x` is not null, `y` otherwise.
72
s1m0nw1

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

Elvis QuestionMark

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

51
Kerooker

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
32
zsmb13

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.

8
Willi Mentzel

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".

0
pauloaap

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, returnempty 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"
0
Romman