Elvis Operator — este un operator binar care returnează operandul stâng dacă nu este null, iar pe cel drept în caz contrar. Se scrie ca ?: în Kotlin, Groovy și în alte câteva limbaje. Conform Kotlin Language Documentation, 2024, operatorul face parte din sistemul de null-siguranță al limbajului și permite reducerea construcțiilor condiționale la o singură linie fără pierderea citibilității. Spre deosebire de scrierea completă if-else, Elvis Operator calculează partea dreaptă doar când valoarea stângă este null, ceea ce oferă un avantaj de performanță la utilizarea expresiilor costisitoare implicite.
Puncte principale
Elvis Operator — un operator binar numit după coafura lui Elvis Presley. Simbolul ?: amintește vizual de fața cântărețului din profil: semnul întrebării — ochiul și perciunii, două puncte — gura. Operatorul primește doi operanzi: dacă primul nu este null — se returnează el, altfel se returnează al doilea. Acest lucru permite înlocuirea unei construcții complete if-else cu o singură scriere scurtă.
Denumirea „Elvis Operator” s-a fixat în comunitatea Kotlin și Groovy, apoi a trecut în Xtend și alte limbaje JVM. În Swift și Dart, construcția similară se numește nil-coalescing operator, dar este funcțional identică. Asociația vizuală cu Elvis Presley a ajutat operatorul să devină unul dintre cele mai recunoscute simboluri în sintaxa limbajelor de programare moderne.
Elvis Operator face parte din sistemul null safety care previne NullPointerException (NPE). Conform unui studiu JetBrains din 2023, NPE constituie 28% din toate excepțiile în codul de producție pe JVM. Utilizarea Elvis Operator elimină complet NPE în punctul de atribuire, garantând o valoare implicită. În combinație cu operatorul de apel sigur ?. se obține un lanț fiabil fără niciun bloc if.
În Kotlin, Elvis Operator se scrie ca ?: între două expresii. Dacă expresia stângă nu este null — rezultatul este egal cu stânga, altfel se calculează dreapta. Expresia dreaptă se calculează leneș — doar când operandul stâng este null, ceea ce este important pentru performanță la utilizarea calculelor costisitoare sau a apelurilor 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 cu throw pentru parametri obligatorii
val requiredId = nullableId ?: throw IllegalArgumentException("ID is required")
// Elvis cu return pentru ieșire timpurie
fun process(data: String?): Result {
val safe = data ?: return Result.failure("No data")
return processInternal(safe)
}
Combinarea cu let — un model frecvent în Kotlin, unde Elvis Operator stabilește valoarea implicită, iar let execută o acțiune cu rezultatul non-null. Această abordare înlocuiește blocuri întregi if-else cu un singur lanț de apeluri fără pierderea citibilității. Elvis Operator poate fi folosit și cu throw pentru întreruperea forțată în lipsa unui parametru obligatoriu — aceasta este o modalitate idiomatică de validare a datelor de intrare.
În Kotlin este răspândit modelul Elvis + return. Dacă valoarea este null, funcția returnează imediat un rezultat sau aruncă o excepție. Idiomul „Elvis with return” este adesea folosit în funcțiile de transformare a datelor: val processed = rawData ?: return defaultValue. Este mai compact decât guard let în Swift și nu crește adâncimea de imbricare a codului.
Elvis Operator este mai scurt decât if-else și nu necesită repetarea variabilei. Comparați: val x = a ?: b versus val x = if (a != null) a else b. La expresii complexe, reducerea codului atinge 60%, iar semantica este complet identică — compilatorul poate genera același byte-code pentru ambele variante.
| Criteriu | Elvis Operator | if-else |
|---|---|---|
| Lungimea scrierii | 1 linie, 5–10 caractere | 3 linii, 15–30 caractere |
| Repetarea expresiei | Nu | Da (a != null) ? a : b |
| Leneșa părții drepte | Da | Da (elvis mai scurt) |
| Efecte secundare | Doar în partea dreaptă | În ambele ramuri |
| Citibilitate | Ridicată pentru cazuri simple | Mai bună pentru logică complexă |
Elvis Operator este optim pentru atribuirea valorii implicite, apelarea lanțurilor de funcții cu acces sigur și logarea valorilor lipsă. Modelele idiomatice Kotlin îl recomandă ca înlocuitor pentru if-else în verificări simple de null în expresii. În combinație cu ?. oferă lanțuri compacte fără variabile temporare.
if-else rămâne preferabil în cazul condițiilor multiple, când trebuie executate efecte secundare sau când ambii operanzi sunt blocuri de cod complexe cu mai multe operații. Elvis Operator nu suportă blocuri imbricate — doar expresii simple pentru fiecare operand. Dacă partea dreaptă apelează o funcție cu efect secundar, citibilitatea if-else este mai mare.
Groovy folosește exact aceeași sintaxă ?: ca și Kotlin, deoarece ambele limbaje rulează pe JVM și împărtășesc filosofia null-safety. În Groovy, operatorul a apărut mai devreme — era în limbaj din versiunea 1.8, lansată în 2011. Groovy suportă și atribuirea Elvis: x ?= value (atribuie doar dacă x este null).
def name = getUserName()
def display = name ?: "Guest"
def map = ["key": "value"]
def result = map?.get("missing") ?: "default"
println(result)
// Atribuirea Elvis în Groovy
def config = null
config ?= "defaultConfig"
assert config == "defaultConfig"
În Swift, analogul se numește nil-coalescing operator și se scrie ca ??. În Dart se folosește aceeași sintaxă ??. Diferența este că Swift și Dart necesită potrivirea tipurilor operandilor, iar Kotlin permite tipuri diferite cu conversie automată la supertipul comun. În TypeScript din versiunea 3.7 a apărut operatorul ?? (nullish coalescing), care funcționează doar cu null și undefined, spre deosebire de || care filtrează toate valorile falsy. În PHP din versiunea 7.0 a apărut operatorul ??, în C# — ?? din versiunea 6.0.
Cea mai frecventă greșeală — confundarea Elvis Operator ?: cu operatorul de apel sigur ?. În Kotlin, ?. apelează o metodă sau proprietate doar dacă obiectul nu este null, iar ?: returnează o valoare implicită la null. Se combină secvențial, dar fiecare își îndeplinește propria funcție. Confuzia apare la începătorii care încearcă să folosească ?: fără ?. în față.
Partea dreaptă a Elvis se calculează leneș, dar dacă în ea se află un apel de funcție cu efecte secundare, aceasta poate duce la un comportament neașteptat. Dezvoltatorii plasează uneori în partea dreaptă calcule costisitoare sau logare care nu se execută când valoarea nu este null. Este important de reținut că partea dreaptă este o expresie care se calculează doar la necesitate.
Mai mulți Elvis consecutivi pot îngreuna citirea codului. De exemplu, a ?: b ?: c ?: d se execută de la stânga la dreapta, returnând primul non-null. Gruparea prin paranteze sau extragerea logicii într-o funcție separată crește citibilitatea și ușurează depanarea. Dacă lanțul este mai lung de 3 elemente, merită să folosiți expresia when sau o funcție auxiliară.
Dezvoltatorii începători încearcă uneori să folosească Elvis Operator pentru verificarea valorilor booleene: val x = flag ?: false. Aceasta funcționează doar dacă flag poate fi null. Pentru condiții booleene fără null este necesar if-else obișnuit sau operatorul ternar, care în Kotlin nu există, dar este înlocuit de expresia if-else: val x = if (flag) a else b.
Întrebări frecvente
Elvis Operator verifică doar null, iar operatorul ternar acceptă orice condiție booleană. În Kotlin nu există operator ternar — este înlocuit de expresia if-else. Elvis rezolvă o sarcină specifică: valoarea implicită la null, pe când operatorul ternar acoperă toate expresiile condiționale.
Da, în partea dreaptă poate fi un apel de funcție: val x = a ?: calculateDefault(). Funcția se calculează doar când valoarea a este null datorită calculului leneș. Acest lucru permite utilizarea calculelor costisitoare, a apelurilor API sau a interogărilor de baze de date fără pierdere de performanță când valoarea există.
În Java nu există Elvis Operator direct. Începând cu Java 8 se poate folosi Optional.ofNullable(value).orElse(default). În Java 14+ au apărut expresiile switch, dar ?: complet lipsește. Kotlin și Groovy îl oferă ca o construcție sintactică încorporată a limbajului.
Modelul tipic: safe call ?. apoi Elvis. Exemplu: user?.address?.city ?: "Unknown". Dacă orice element al lanțului este null — se returnează valoarea implicită. Aceasta este o înlocuire compactă a verificărilor if imbricate, care reduce codul de 3–5 ori comparativ cu abordarea tradițională.
Elvis Operator este o construcție sintactică la nivel de limbaj, orElse este o metodă Optional în Java. Elvis se execută leneș (partea dreaptă se calculează doar la null), orElse calculează întotdeauna argumentul. Pentru varianta leneșă în Java există orElseGet, care acceptă un Supplier. Elvis este mai scurt și nu necesită crearea unui Optional.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și