Cosa fa?: Fare a Kotlin? (Operatore Elvis)


98

Non riesco a capire cosa ?:ci sia ad esempio in questo caso

val list = mutableList ?: mutableListOf() 

e perché può essere modificato in questo

val list = if (mutableList != null) mutableList else mutableListOf()

5
Ritorna a sinistra se non è nullo, altrimenti torna a destra. La prima espressione è una breve notazione per la seconda espressione. kotlinlang.org/docs/reference/null-safety.html#elvis-operator
Eugen Pechanec

Risposte:


115

TL; DR: se il riferimento all'oggetto risultante [primo operando] non nulllo è, viene restituito. In caso contrario, nullviene restituito il valore del secondo operando (che potrebbe essere )


L' operatore Elvis fa parte di molti linguaggi di programmazione, ad esempio Kotlin ma anche Groovy o C #. Trovo la definizione di Wikipedia piuttosto accurata:

In alcuni linguaggi di programmazione per computer, l' operatore Elvis ?: è un operatore binario che restituisce il suo primo operando se tale operando è true, e altrimenti valuta e restituisce il suo secondo operando. Si tratta di una variante del operatore condizionale ternario , ? :, trova in quelle lingue (e molti altri): l'operatore Elvis è l' operatore ternario con il secondo operando omessa .

Quanto segue è particolarmente vero per Kotlin:

Alcuni linguaggi di programmazione per computer hanno semantica diversa per questo operatore. Invece del primo operando che deve risultare in un booleano, deve risultare in un riferimento a un oggetto . Se il riferimento all'oggetto risultante non nulllo è, viene restituito. In caso contrario, nullviene restituito il valore del secondo operando (che potrebbe essere ).

Un esempio:

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

3
Questo è davvero fantastico. Non avrei mai pensato che elvis operatorpotesse essere ulteriormente ridotto a qualcos'altro. simpatico! E bella spiegazione, grazie!
sud007

88

L' operatore Elvis è rappresentato da un punto interrogativo seguito da due punti: ?:e può essere utilizzato con questa sintassi:

first operand ?: second operand

Ti consente di scrivere un codice coerente e funziona come tale:

Se first operand non è nullo , verrà restituito. Se è nullo , second operandverrà restituito. Questo può essere usato per garantire che un'espressione non restituisca un valore null, poiché fornirai un valore non nullable se il valore fornito è null.


Ad esempio (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"
}

In questo caso, se il valore calcolato di getPotentialNullnon è nullo, verrà restituito da retrieveString; Se è null, "Secondary Not-Null String"verrà invece restituita la seconda espressione .

Si noti inoltre che l'espressione del lato destro viene valutata solo se il lato sinistro è nullo .

In Kotlin, puoi usare qualsiasi espressione come second operand, come throw Exceptionun'espressione

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

Il nome Elvis Operator deriva dal famoso cantante americano Elvis Presley . La sua acconciatura ricorda un punto interrogativo

Elvis QuestionMark

Fonte: Wojda, I. Moskala, M. Sviluppo Android con Kotlin. 2017. Packt Publishing


84
Più 1 per aver illustrato Mr Presley
s1m0nw1

7
? :) (vedi Elvis che sorride)
LeoColman

1
Dopo un po ', non riesco a capire perché si chiama Elvis Operator. La tua illustrazione mi ha fatto capire perché si chiama Elvis Operator. :)
Yohanes AI

la storia di Elvis è davvero vera? haha
Hillcow

@Kerooker Non sta sorridendo,?: | sarà migliore IMO.
ahmed galal

38

Questo si chiama operatore Elvis e fa ... Esattamente quello che hai descritto nella tua domanda. Se il suo lato sinistro è un nullvalore, restituisce invece il lato destro, una sorta di riserva. Altrimenti restituisce solo il valore sul lato sinistro.

a ?: bè solo una scorciatoia per if (a != null) a else b.

Alcuni altri esempi con i tipi:

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

10
se vieni da java, è più una scorciatoia per:a != null ? a : b
crgarridos

9

Diamo un'occhiata alla definizione :

Quando abbiamo un riferimento nullable r, possiamo dire "se r non è nullo, usalo, altrimenti usa un valore x non nullo":

L' ?:operatore (Elvis) evita la verbosità e rende il tuo codice davvero conciso.

Ad esempio, molte funzioni di estensione della raccolta restituiscono nullcome fallback.

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

?:ti offre un modo per gestire il caso di fallback in modo elgante anche se hai più livelli di fallback. In tal caso, puoi semplicemente concatenare moltiplicare gli operatori Elvis, come qui:

val l = listOf(1, 2, 3)

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

Se esprimessi lo stesso con se altrimenti sarebbe molto più codice che è più difficile da leggere.


3

Possiamo semplicemente dire che hai due mani. Vuoi sapere, la tua mano sinistra sta lavorando in questo momento? Se la mano sinistra non funziona, return emptyaltrimentibusy

Esempio per Java:

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

Esempio per Kotlin:

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

Amo questa risposta. Troppo pulito per capire.
Gk Mohammad Emon

2

Fondamentalmente, se il lato sinistro di Elvis restituisce null per qualche motivo, restituisce invece il lato destro.

cioè

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

Quindi, se il numero NON è nullo , stamperà il numero, altrimenti stamperà "Il numero è nullo".


1

L'operatore elvis in Kotlin viene utilizzato per la sicurezza nulla.

x = a ?: b

Nel codice sopra, xverrà assegnato il valore di ase a non è nulle bse aènull .

Il codice kotlin equivalente senza utilizzare l'operatore elvis è di seguito:

x = if(a == null) b else a

1

Una piccola aggiunta però è questa

X = A ?: B

Xsarà ancora nullse entrambi Ae Bvalutarenull

Pertanto, se vuoi Xessere sempre non-null, assicurati che Bsia sempre a non-nullo che Bvaluti sempre non-nullse è una funzione o un'espressione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.