Elvis Operator è un operatore binario che restituisce l’operando sinistro se non è null, e quello destro in caso contrario. Si scrive come ?: in Kotlin, Groovy e alcuni altri linguaggi. Secondo la Documentazione del linguaggio Kotlin, 2024, l’operatore fa parte del sistema di sicurezza null del linguaggio e consente di ridurre le costruzioni condizionali a una singola riga senza perdere leggibilità. A differenza di un’espressione if-else completa, l’Elvis Operator valuta la parte destra solo quando la parte sinistra è null, offrendo un vantaggio in termini di prestazioni quando si utilizzano espressioni predefinite costose.
Punti chiave
Elvis Operator è un operatore binario chiamato così per l’acconciatura di Elvis Presley. Il simbolo ?: ricorda visivamente il volto del cantante di profilo: il punto interrogativo è l’occhio e le basette, i due punti sono la bocca. L’operatore prende due operandi: se il primo non è null — viene restituito quello, altrimenti viene restituito il secondo. Ciò consente di sostituire un’intera costruzione if-else con una singola espressione breve.
Il nome “Elvis Operator” si è affermato nelle comunità di Kotlin e Groovy, per poi diffondersi in Xtend e altri linguaggi JVM. In Swift e Dart, la costruzione analoga è chiamata nil-coalescing operator, ma è funzionalmente identica. L’associazione visiva con Elvis Presley ha aiutato l’operatore a diventare uno dei simboli più riconoscibili nella sintassi dei linguaggi di programmazione moderni.
L’Elvis Operator fa parte del sistema null safety che previene NullPointerException (NPE). Secondo uno studio JetBrains del 2023, NPE rappresenta il 28% di tutte le eccezioni nel codice JVM in produzione. L’uso dell’Elvis Operator elimina completamente NPE nel punto di assegnazione, garantendo un valore predefinito. In combinazione con l’operatore di chiamata sicura ?., viene creata una catena affidabile senza un singolo blocco if.
In Kotlin, l’Elvis Operator si scrive come ?: tra due espressioni. Se l’espressione sinistra non è null — il risultato è uguale all’espressione sinistra, altrimenti viene valutata quella destra. L’espressione destra viene valutata pigramente — solo quando l’operando sinistro è null, il che è importante per le prestazioni quando si utilizzano calcoli costosi o chiamate API.
val name: String? = getUserName()
val displayName = name ?: "Guest"
fun getLength(str: String?): Int {
return str?.length ?: 0
}
val config: Config? = loadConfig()
val timeout = config?.timeout ?: 30
println("Timeout: $timeout")
// Elvis with throw per parametri obbligatori
val requiredId = nullableId ?: throw IllegalArgumentException("ID is required")
// Elvis with return per uscita anticipata
fun process(data: String?): Result {
val safe = data ?: return Result.failure("No data")
return processInternal(safe)
}
Combinazione con let è un modello comune in Kotlin, dove l’Elvis Operator fornisce un valore predefinito e let esegue un’azione sul risultato non null. Questo approccio sostituisce interi blocchi if-else con una singola catena di chiamate senza perdere leggibilità. L’Elvis Operator può anche essere utilizzato con throw per interrompere forzatamente in assenza di un parametro obbligatorio — questo è un modo idiomatico per validare i dati di input.
Un modello comune in Kotlin è Elvis + return. Se il valore è null, la funzione restituisce immediatamente un risultato o lancia un’eccezione. L’idioma Elvis con return viene spesso utilizzato nelle funzioni di trasformazione dei dati: val processed = rawData ?: return defaultValue. È più compatto di guard let in Swift e non aumenta l’annidamento del codice.
Elvis Operator è più corto di if-else e non richiede di ripetere la variabile. Confrontate: val x = a ?: b versus val x = if (a != null) a else b. Con espressioni complesse, la riduzione del codice raggiunge il 60%, mentre la semantica è completamente identica — il compilatore può generare lo stesso bytecode per entrambe le varianti.
| Criterio | Elvis Operator | if-else |
|---|---|---|
| Lunghezza | 1 riga, 5–10 caratteri | 3 righe, 15–30 caratteri |
| Ripetizione dell’espressione | No | Sì (a != null) ? a : b |
| Lato destro pigro | Sì | Sì (elvis è più corto) |
| Effetti collaterali | Solo sul lato destro | In entrambi i rami |
| Leggibilità | Alta per casi semplici | Migliore per logica complessa |
L’Elvis Operator è ottimale per assegnare valori predefiniti, concatenare chiamate di funzioni con accesso sicuro e registrare valori mancanti. I modelli idiomatici di Kotlin lo raccomandano come sostituto di if-else per controlli null semplici nelle espressioni. In combinazione con ?., produce catene compatte senza variabili temporanee.
if-else rimane preferibile per condizioni multiple, quando è necessario eseguire effetti collaterali, o quando entrambi gli operandi sono blocchi di codice complessi con diverse operazioni. L’Elvis Operator non supporta blocchi annidati — solo espressioni singole per ciascun operando. Se il lato destro chiama una funzione con effetti collaterali, la leggibilità di if-else è maggiore.
Groovy utilizza esattamente la stessa sintassi ?: di Kotlin, poiché entrambi i linguaggi funzionano sulla JVM e condividono la filosofia null-safety. L’operatore è apparso prima in Groovy — è presente nel linguaggio dalla versione 1.8, rilasciata nel 2011. Groovy supporta anche l’assegnazione Elvis: x ?= value (assegna solo se x è null).
def name = getUserName()
def display = name ?: "Guest"
def map = ["key": "value"]
def result = map?.get("missing") ?: "default"
println(result)
// Assegnazione Elvis in Groovy
def config = null
config ?= "defaultConfig"
assert config == "defaultConfig"
In Swift, l’equivalente si chiama nil-coalescing operator e si scrive ??. In Dart viene utilizzata la stessa sintassi ??. La differenza è che Swift e Dart richiedono la corrispondenza dei tipi degli operandi, mentre Kotlin consente tipi diversi con conversione automatica a un supertipo comune. In TypeScript, l’operatore ?? (nullish coalescing) è apparso nella versione 3.7 e funziona solo con null e undefined, a differenza di || che filtra tutti i valori falsy. In PHP, l’operatore ?? è apparso nella versione 7.0, in C# — ?? dalla versione 6.0.
L’errore più frequente è confondere l’Elvis Operator ?: con l’operatore di chiamata sicura ?. In Kotlin, ?. chiama un metodo o una proprietà solo se l’oggetto non è null, mentre ?: restituisce un valore predefinito quando è null. Vengono combinati sequenzialmente, ma ciascuno svolge la propria funzione. La confusione nasce tra i principianti che cercano di usare ?: senza ?. davanti.
Il lato destro di Elvis viene valutato pigramente, ma se contiene una chiamata di funzione con effetti collaterali, può portare a un comportamento inaspettato. Gli sviluppatori a volte inseriscono calcoli costosi o logging nel lato destro, che non viene eseguito quando il valore non è nullo. È importante ricordare che il lato destro è un’espressione che viene valutata solo quando necessario.
Diversi Elvis consecutivi possono complicare la lettura del codice. Ad esempio, a ?: b ?: c ?: d viene valutato da sinistra a destra, restituendo il primo non null. Il raggruppamento tramite parentesi o l’estrazione della logica in una funzione separata migliora la leggibilità e facilita il debug. Se la catena è più lunga di 3 elementi, si dovrebbe usare un’espressione when o una funzione di supporto.
Gli sviluppatori principianti a volte cercano di usare l’Elvis Operator per verificare valori booleani: val x = flag ?: false. Ciò funziona solo se flag può essere null. Per condizioni booleane senza null, è necessario un normale if-else o operatore ternario — Kotlin non ha un operatore ternario, ma viene sostituito dall’espressione if-else: val x = if (flag) a else b.
Domande frequenti
Elvis Operator controlla solo se c’è null, mentre l’operatore ternario accetta qualsiasi condizione booleana. Kotlin non ha un operatore ternario — viene sostituito dall’espressione if-else. Elvis risolve un compito specifico: un valore predefinito in caso di null, mentre l’operatore ternario copre tutte le espressioni condizionali.
Sì, il lato destro può essere una chiamata di funzione: val x = a ?: calculateDefault(). La funzione viene valutata solo quando a è null grazie alla valutazione pigra. Ciò consente di utilizzare calcoli costosi, chiamate API o query al database senza perdita di prestazioni quando è presente un valore.
Java non ha un Elvis Operator diretto. A partire da Java 8, è possibile utilizzare Optional.ofNullable(value).orElse(default). Java 14+ ha introdotto le espressioni switch, ma un ?: completo è assente. Kotlin e Groovy lo forniscono come costruzione sintattica integrata del linguaggio.
Il modello tipico è una chiamata sicura ?. seguita da Elvis. Esempio: user?.address?.city ?: “Unknown”. Se un qualsiasi elemento della catena è null — viene restituito il valore predefinito. È un sostituto compatto per i controlli if annidati, che riduce il codice di 3–5 volte rispetto all’approccio tradizionale.
Elvis Operator è una costruzione sintattica a livello di linguaggio, mentre orElse è un metodo di Optional in Java. Elvis è pigro (il lato destro viene valutato solo quando null), mentre orElse valuta sempre il suo argomento. Per una variante pigra in Java, esiste orElseGet che accetta un Supplier. Elvis è più corto e non richiede la creazione di un Optional.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche