Was macht ?: In Kotlin? (Elvis-Betreiber)

92

Ich kann nicht herausfinden, was ?:zum Beispiel in diesem Fall passiert

val list = mutableList ?: mutableListOf() 

und warum kann es daran geändert werden

val list = if (mutableList != null) mutableList else mutableListOf()
Jocas
quelle
5
Geben Sie die linke Seite zurück, wenn sie nicht null ist, andernfalls die rechte Seite. Der erste Ausdruck ist eine Kurzschreibweise für den zweiten Ausdruck. kotlinlang.org/docs/reference/null-safety.html#elvis-operator
Eugen Pechanec

Antworten:

112

TL; DR: Wenn die resultierende Objektreferenz [erster Operand] nicht vorhanden ist null, wird sie zurückgegeben. Andernfalls wird der Wert des zweiten Operanden (möglicherweise null) zurückgegeben


Der Elvis-Operator ist Teil vieler Programmiersprachen, z. B. Kotlin, aber auch Groovy oder C #. Ich finde die Wikipedia- Definition ziemlich genau:

In bestimmten Computerprogrammiersprachen ist der Elvis-Operator ?: ein binärer Operator , der seinen ersten Operanden zurückgibt, wenn dieser Operand ist true, und ansonsten seinen zweiten Operanden auswertet und zurückgibt. Es ist eine Variante des ternären bedingten Operators , ? :der in diesen Sprachen (und vielen anderen) vorkommt: Der Elvis-Operator ist der ternäre Operator, dessen zweiter Operand weggelassen wird .

Folgendes gilt insbesondere für Kotlin:

Einige Computerprogrammiersprachen haben für diesen Operator eine andere Semantik. Anstatt dass der erste Operand zu einem Booleschen Wert führen muss, muss er zu einer Objektreferenz führen . Wenn die resultierende Objektreferenz nicht vorhanden ist null, wird sie zurückgegeben. Andernfalls wird der Wert des zweiten Operanden (möglicherweise null) zurückgegeben.

Ein Beispiel:

x ?: y // yields `x` if `x` is not null, `y` otherwise.
s1m0nw1
quelle
3
Das ist wirklich cool. Ich hätte nie gedacht, elvis operatordass ich weiter auf etwas anderes reduziert werden könnte. nett! Und schöne Erklärung, danke!
Sud007
83

Der Elvis-Operator wird durch ein Fragezeichen gefolgt von einem Doppelpunkt dargestellt. ?:Er kann mit folgender Syntax verwendet werden:

first operand ?: second operand

Es ermöglicht Ihnen das Schreiben eines konsistenten Codes und funktioniert als solcher:

Wenn first operand nicht null ist , wird es zurückgegeben. Wenn es null ist , second operandwird das zurückgegeben. Dies kann verwendet werden, um sicherzustellen, dass ein Ausdruck keinen Nullwert zurückgibt, da Sie einen nicht nullbaren Wert angeben, wenn der angegebene Wert null ist.


Zum Beispiel (in 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"
}

Wenn in diesem Fall der berechnete Wert von getPotentialNullnicht null ist, wird er von zurückgegeben retrieveString. Wenn es null ist, "Secondary Not-Null String"wird stattdessen der zweite Ausdruck zurückgegeben.

Beachten Sie auch, dass der Ausdruck auf der rechten Seite nur ausgewertet wird , wenn der Ausdruck auf der linken Seite null ist .

In Kotlin können Sie einen beliebigen Ausdruck als verwenden second operand, z. B. einen throw ExceptionAusdruck

return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")

Der Name Elvis Operator stammt von dem berühmten amerikanischen Sänger Elvis Presley . Seine Frisur ähnelt einem Fragezeichen

Elvis QuestionMark

Quelle: Wojda, I. Moskala, M. Android-Entwicklung mit Kotlin. 2017. Packt Publishing

LeoColman
quelle
78
Plus 1 für die Veranschaulichung von Herrn Presley
s1m0nw1
7
? :) (sehen Sie es als Elvis lächelnd)
LeoColman
1
Nach einer Weile kann ich nicht verstehen, warum es Elvis Operator heißt. Ihre Illustration hat mich wissen lassen, warum es Elvis Operator heißt. :)
Yohanes AI
Ist die Geschichte über Elvis tatsächlich wahr? haha
Hillcow
@Kerooker Er lächelt nicht,?: | wird besser IMO sein.
Ahmed Galal
37

Dies wird als Elvis-Operator bezeichnet und tut es ... Genau das, was Sie in Ihrer Frage beschrieben haben. Wenn die linke Seite ein nullWert ist, wird stattdessen die rechte Seite zurückgegeben, sozusagen als Fallback. Andernfalls wird nur der Wert auf der linken Seite zurückgegeben.

a ?: bist nur eine Abkürzung für if (a != null) a else b.

Einige weitere Beispiele mit Typen:

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
quelle
9
Wenn Sie aus Java kommen, ist es eher eine Abkürzung für:a != null ? a : b
Crgarridos
9

Werfen wir einen Blick auf die Definition :

Wenn wir eine nullfähige Referenz r haben, können wir sagen "Wenn r nicht null ist, verwenden Sie es, andernfalls verwenden Sie einen Nicht-Null-Wert x":

Der ?:Operator (Elvis) vermeidet Ausführlichkeit und macht Ihren Code wirklich präzise.

Beispielsweise werden viele Funktionen zur Sammlungserweiterung nullals Fallback zurückgegeben.

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

?:bietet Ihnen die Möglichkeit, den Fallback-Fall auch bei mehreren Fallback-Schichten elegant zu behandeln. Wenn ja, können Sie einfach Elvis-Operatoren wie hier verketten:

val l = listOf(1, 2, 3)

val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")

Wenn Sie dasselbe mit wenn sonst ausdrücken würden, wäre es viel mehr Code, der schwerer zu lesen ist.

Willi Mentzel
quelle
2

Wir können einfach sagen, dass Sie zwei Hände haben. Sie möchten wissen, ob Ihre linke Hand gerade arbeitet? Wenn die linke Hand nicht funktioniert, return emptysonstbusy

Beispiel für Java:

private int a;
if(a != null){
    println("a is not null, Value is: "+a)
}
else{
    println("a is null")
}

Beispiel für Kotlin:

val a : Int = 5
val l : Int = if (a != null) a.length else "a is null"
Romman
quelle
2

Wenn die linke Seite von Elvis aus irgendeinem Grund null zurückgibt, wird grundsätzlich stattdessen die rechte Seite zurückgegeben.

dh

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

Also, wenn die Zahl nicht Null ist , wird es drucken Nummer, andernfalls wird gedruckt „Number ist null“.

pauloaap
quelle
1

Der elvis-Operator in Kotlin wird aus Sicherheitsgründen verwendet.

x = a ?: b

Im obigen Code xwird der Wert zugewiesen, awenn a nicht ist nullund bwenn aist null.

Der entsprechende Kotlin-Code ohne Verwendung des elvis-Operators ist unten aufgeführt:

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

Eine kleine Ergänzung ist dies

X = A ?: B

Xwird immer noch sein, nullwenn beide Aund Bbewertennull

Wenn Sie Ximmer sein möchten non-null, stellen Sie daher sicher, dass Bes sich immer um eine handelt non-nulloder dass Bimmer ausgewertet wird, non-nullob es sich um eine Funktion oder einen Ausdruck handelt.

Wilson
quelle