Lambda — este o funcție anonimă prezentată sub forma unei expresii compacte { argumente -> corp }. În Kotlin, lambda-urile sunt modul principal de a transmite comportamentul către funcțiile de ordin superior (higher-order functions), oferind o sintaxă concisă fără a fi nevoie să declari o funcție separată. Conform documentației Kotlin (2026), peste 70% din funcțiile de ordin superior din proiectele tipice sunt apelate cu lambda-uri. Lambda permite scrierea codului în stil funcțional cu un minim de zgomot sintactic.
Principalele puncte
Lambda (expresie lambda) — este o funcție anonimă definită sub formă de expresie, nu de declarație. Termenul provine de la calculul lambda al lui Alonzo Church (1936). În programare, lambda reprezintă un bloc de cod care poate fi transmis ca valoare, stocat într-o variabilă și apelat ulterior. În Kotlin, lambda este întotdeauna cuprinsă între acolade { }, argumentele fiind separate de corp prin săgeata ->.
Lambda se deosebește de o funcție obișnuită prin absența numelui și a cuvântului cheie fun. Acest lucru permite declararea comportamentului direct în punctul de utilizare, fără a aglomera codul cu declarații suplimentare. Compilatorul Kotlin deduce tipurile argumentelor din context, deci în multe cazuri tipurile pot fi omise. Lambda este zahăr sintactic peste tipul funcțional (T) -> R: fiecare lambda are un tip funcțional corespunzător.
Utilizarea principală a lambda-urilor în Kotlin este transmiterea către funcții de ordin superior (higher-order functions). Biblioteca standard folosește lambda-uri peste tot: filter { it > 0 }, map { it.uppercase() }, forEach { println(it) }. Lambda-urile sunt, de asemenea, utilizate pentru a crea ascultători de evenimente, callback-uri, configuratori de obiecte prin apply și run, ceea ce face codul mai declarativ în comparație cu clasele anonime.
Forma completă a expresiei lambda în Kotlin: { argumente -> corp_lambda }. Argumentele sunt enumerate cu virgulă, urmate de săgeată și corp — una sau mai multe expresii. Dacă corpul conține mai multe linii, ultima expresie devine valoarea returnată. Dacă funcția acceptă lambda ca ultim argument, aceasta poate fi scoasă în afara parantezelor de apel.
val sum: (Int, Int) -> Int = { a, b -> a + b }
// Tipuri deduse din context
val sumShort = { a: Int, b: Int -> a + b }
// Apel lambda
val result = sum(5, 3) // 8
println(result)
Variabila sum este declarată cu tipul funcțional explicit (Int, Int) -> Int și inițializată cu lambda { a, b -> a + b }. Pentru sumShort tipurile sunt specificate în interiorul lambda-ului, iar tipul variabilei este dedus. Ambele variante sunt echivalente. Apelarea lambda-ului nu diferă de apelarea unei funcții obișnuite — se folosește sintaxa sum(5, 3). Lambda fără argumente se scrie ca { body }, cu un argument — { it -> it * 2 } sau pur și simplu { it * 2 }.
Când lambda acceptă exact un argument, Kotlin oferă numele implicit it. Acest lucru elimină necesitatea de a declara argumentul în partea stângă. Programatorul scrie doar corpul lambda-ului, folosind it pentru a accesa singurul parametru. O astfel de sintaxă este deosebit de convenabilă în lanțurile de procesare a colecțiilor, unde it denotă elementul curent.
val numbers = listOf(1, 2, 3, 4, 5)
// Nume explicit de parametru
val squaredExplicit = numbers.map { n -> n * n }
// it implicit
val squared = numbers.map { it * it }
// Filtrare cu it
val even = numbers.filter { it % 2 == 0 }
println(squared) // [1, 4, 9, 16, 25]
În exemplul map { it * it } se folosește it în locul declarației n ->. Kotlin atribuie automat it pentru singurul parametru al lambda-ului. Dacă lambda acceptă două sau mai multe argumente, it nu este creat — trebuie să declarați toți parametrii explicit. Pentru o mai bună lizibilitate a lambda-urilor imbricate, este recomandat să dați parametrilor nume semnificative și să folosiți it în predicate scurte de o singură linie.
Trailing lambda (lambda finală) — o caracteristică sintactică a Kotlin care permite scoaterea ultimului argument-lambda în afara parantezelor rotunde ale apelului funcției. Acest lucru face codul să semene cu construcțiile limbajului încorporate. Dacă lambda este singurul argument, parantezele pot fi omise complet. Această abordare este utilizată activ în biblioteca standard și în DSL.
// Apel standard
thread(block = {
println("Salut din fir")
})
// Versiunea trailing lambda
thread {
println("Salut din fir")
}
// repeat cu trailing lambda
repeat(3) { index ->
println("Iterația $index")
}
// run cu lambda multiline
val config = run {
val host = "localhost"
val port = 8080
"$host:$port"
}
Funcția thread acceptă Runnable ca ultim argument. Datorită trailing lambda, se poate transmite lambda în afara parantezelor, ceea ce vizual seamănă cu un bloc de cod. Funcția repeat acceptă numărul de iterații și un lambda cu indice. run — un exemplu de funcție de ordin superior, unde un lambda multiline calculează valoarea returnată de ultima expresie. Parantezele din jurul run() pot fi omise dacă lambda este singurul argument.
Captarea variabilelor (closure) — capacitatea lambda-ului de a accesa variabile declarate în domeniul de vizibilitate extern. În Kotlin, lambda poate citi și modifica variabile var, precum și citi variabile val din contextul înconjurător. Variabilele captate sunt stocate împreună cu lambda pe toată durata ciclului său de viață, ceea ce permite crearea de funcții cu stare.
fun makeCounter(): () -> Int {
var count = 0
return {
count++ // număr capturi
}
}
fun main() {
val counter = makeCounter()
println(counter()) // 0
println(counter()) // 1
println(counter()) // 2
}
Funcția makeCounter declară o variabilă locală count și returnează lambda { count++ }. Deși makeCounter și-a încheiat execuția, lambda returnată păstrează referința la count prin închidere (closure). Fiecare apel counter() incrementează și returnează valoarea curentă. Mecanismul closure stă la baza currying-ului, fabricilor de funcții și memoizării. Este important de reținut că captarea variabilelor mutabile poate duce la comportament neașteptat în execuția paralelă.
Întrebări frecvente
Lambda nu suportă return necondiționat — return fără etichetă returnează controlul funcției externe. Pentru a ieși din lambda, folosiți return@label, unde label este numele funcției de ordin superior căreia i-a fost transmisă lambda.
Funcția anonimă se scrie ca fun(a: Int): Int { return a * 2 } și suportă return fără etichetă. Lambda { a -> a * 2 } este mai scurtă sintactic, dar necesită return@label pentru ieșirea timpurie.
Dacă lambda nu acceptă argumente, săgeata este omisă: { body() }. Dacă acceptă un argument și nu îl folosește, în locul săgeții se scrie { _ -> body() } cu subliniere pentru ignorarea parametrului.
Da, fiecare lambda transmisă unei funcții non-inline creează o instanță a unei clase anonime. Pentru funcțiile inline, lambda este inserată la locul apelului fără a crea un obiect. Lambda-urile non-capturing sunt cache-uite în obiecte singleton.
Return în Kotlin este un operator de salt care aparține celei mai apropiate funcții cu fun. Lambda nu este o funcție (fun), ci o expresie. Prin urmare, return în interiorul lambda-ului fără etichetă este considerat ca o revenire din funcția externă înconjurătoare.
Rezumat
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