Lambda — { arqumentlər -> bədən } kompakt ifadəsi şəklində təqdim olunan anonim funksiyadır. Kotlin-də lambdalar davranışı ali dərəcəli funksiyalara (higher-order functions) ötürməyin əsas yoludur və ayrıca funksiya elan etmək ehtiyacı olmadan yığcam sintaksis təmin edir. Kotlin sənədlərinə (2026) görə, tipik layihələrdə ali dərəcəli funksiyaların 70%-dən çoxu lambdalarla çağırılır. Lambda minimal sintaksis səs-küyü ilə funksional üslubda kod yazmağa imkan verir.
Əsas məqamlar
Lambda (lambda ifadəsi) — bu, bəyannamə deyil, ifadə şəklində təyin olunan anonim funksiyadır. Termin Alonzo Çörçün (1936) lambda hesabından gəlir. Proqramlaşdırmada lambda dəyər kimi ötürülə bilən, dəyişəndə saxlanıla bilən və sonra çağrıla bilən kod blokunu təmsil edir. Kotlin-də lambda həmişə qıvrım mötərizələr { } içərisində olur, arqumentlər bədəndən -> oxu ilə ayrılır.
Lambda adi funksiyadan adın və fun açar sözünün olmaması ilə fərqlənir. Bu, davranışı birbaşa istifadə nöqtəsində bəyan etməyə imkan verir, kodu əlavə bəyannamələrlə qarışdırmadan. Kotlin kompilyatoru arqumentlərin tiplərini kontekstdən çıxarır, buna görə də bir çox hallarda tipləri buraxmaq olar. Lambda funksional tip (T) -> R üzərində sintaktik şəkərdir: hər bir lambda müvafiq funksional tipə malikdir.
Kotlin-də lambdaların əsas tətbiqi ali dərəcəli funksiyalara (higher-order functions) ötürməkdir. Standart kitabxana lambdalardan hər yerdə istifadə edir: filter { it > 0 }, map { it.uppercase() }, forEach { println(it) }. Lambdalar həmçinin hadisə dinləyiciləri, callback-lər, apply və run vasitəsilə obyekt konfiquratorları yaratmaq üçün istifadə olunur ki, bu da kodu anonim siniflərlə müqayisədə daha deklarativ edir.
Kotlin-də lambda ifadəsinin tam forması: { arqumentlər -> lambda_bədəni }. Arqumentlər vergüllə sadalanır, sonra ox və bədən — bir və ya daha çox ifadə. Bədən bir neçə sətirdən ibarətdirsə, son ifadə qaytarılan dəyər olur. Funksiya lambdanı son arqument kimi qəbul edirsə, onu çağırış mötərizələrindən kənara çıxarmaq olar.
val sum: (Int, Int) -> Int = { a, b -> a + b }
// Kontekstdən çıxarılan tiplər
val sumShort = { a: Int, b: Int -> a + b }
// Lambda çağırışı
val result = sum(5, 3) // 8
println(result)
sum dəyişəni açıq funksional tip (Int, Int) -> Int ilə elan edilmiş və { a, b -> a + b } lambdası ilə işə salınmışdır. sumShort üçün tipler lambda daxilində göstərilmiş, dəyişənin tipi isə çıxarılmışdır. Hər iki variant ekvivalentdir. Lambdanın çağırılması adi funksiyanın çağırılmasından fərqlənmir — sum(5, 3) sintaksisi istifadə olunur. Arqumentsiz lambda { body }, bir arqumentli lambda isə { it -> it * 2 } və ya sadəcə { it * 2 } kimi yazılır.
Lambda düz bir arqument qəbul etdikdə, Kotlin gizli it adını təqdim edir. Bu, arqumenti sol tərəfdə bəyan etmək ehtiyacını aradan qaldırır. Proqramçı yalnız lambda bədənini yazır, tək parametrə daxil olmaq üçün it istifadə edir. Belə sintaksis xüsusilə kolleksiya emal zəncirlərində əlverişlidir, burada it cari elementi bildirir.
val numbers = listOf(1, 2, 3, 4, 5)
// Açıq parametr adı
val squaredExplicit = numbers.map { n -> n * n }
// Gizli it
val squared = numbers.map { it * it }
// it ilə filtrləmə
val even = numbers.filter { it % 2 == 0 }
println(squared) // [1, 4, 9, 16, 25]
Nümunədə map { it * it } it istifadə edir n -> bəyannaməsi əvəzinə. Kotlin avtomatik olaraq it-i lambdanın yeganə parametri üçün təyin edir. Lambda iki və ya daha çox arqument qəbul edərsə, it yaradılmır — bütün parametrləri açıq şəkildə bəyan etmək lazımdır. İç-içə lambdaların oxunaqlılığını artırmaq üçün parametrlərə mənalı adlar vermək, it-i isə qısa təksətirli predikatlarda istifadə etmək məsləhətdir.
Trailing lambda (son lambda) — Kotlin-in sintaktik xüsusiyyətidir, son arqument-lambdanı funksiya çağırışının dairəvi mötərizələrindən kənara çıxarmağa imkan verir. Bu, kodu daxili dil konstruksiyalarına bənzədir. Lambda yeganə arqumentdirsə, mötərizələri tamamilə buraxmaq olar. Bu yanaşma standart kitabxanada və DSL-də fəal şəkildə istifadə olunur.
// Standart çağırış
thread(block = {
println("Salam iplikdən")
})
// Trailing lambda versiyası
thread {
println("Salam iplikdən")
}
// trailing lambda ilə repeat
repeat(3) { index ->
println("İterasiya $index")
}
// çoxsətirli lambda ilə run
val config = run {
val host = "localhost"
val port = 8080
"$host:$port"
}
thread funksiyası Runnable-i son arqument kimi qəbul edir. Trailing lambda sayəsində lambdanı mötərizələrdən kənarda ötürmək olar ki, bu da vizual olaraq kod blokunu xatırladır. repeat funksiyası iterasiya sayını və indeksli lambdanı qəbul edir. run — ali dərəcəli funksiya nümunəsidir, burada çoxsətirli lambda son ifadə ilə qaytarılan dəyəri hesablayır. run() ətrafındakı mötərizələri buraxmaq olar, əgər lambda yeganə arqumentdirsə.
Dəyişənlərin tutulması (klözür) — lambdanın xarici görünmə sahəsində elan edilmiş dəyişənlərə müraciət etmə qabiliyyətidir. Kotlin-də lambda var-dəyişənlərini oxuya və dəyişdirə, həmçinin ətraf kontekstdən val-dəyişənlərini oxuya bilər. Tutulmuş dəyişənlər lambdanın bütün həyat dövrü ərzində onunla birlikdə saxlanılır ki, bu da vəziyyətə malik funksiyalar yaratmağa imkan verir.
fun makeCounter(): () -> Int {
var count = 0
return {
count++ // tutulma sayı
}
}
fun main() {
val counter = makeCounter()
println(counter()) // 0
println(counter()) // 1
println(counter()) // 2
}
makeCounter funksiyası yerli count dəyişənini elan edir və { count++ } lambdasını qaytarır. makeCounter işini bitirmiş olsa da, qaytarılan lambda klözür vasitəsilə count-a istinadı saxlayır. Hər counter() çağırışı cari dəyəri artırır və qaytarır. Klözür mexanizmi karriləmə, funksiya fabrikləri və memoizasiyanın əsasını təşkil edir. Dəyişdirilə bilən dəyişənlərin tutulmasının paralel icrada gözlənilməz davranışa səbəb ola biləcəyini xatırlamaq vacibdir.
Tez-tez verilən suallar
Lambda qeyd-şərtsiz return-u dəstəkləmir — etiketsiz return xarici funksiyaya idarəni qaytarır. Lambdadan çıxmaq üçün return@label istifadə edin, burada label lambdanın ötürüldüyü ali dərəcəli funksiyanın adıdır.
Anonim funksiya fun(a: Int): Int { return a * 2 } kimi yazılır və etiketsiz return-u dəstəkləyir. Lambda { a -> a * 2 } sintaksis baxımından daha qısadır, lakin erkən çıxış üçün return@label tələb edir.
Lambda arqument qəbul etmirsə, ox buraxılır: { body() }. Bir arqument qəbul edib istifadə etmirsə, ox yerinə { _ -> body() } yazılır və parametr alt xəttlə işarələnir.
Bəli, non-inline funksiyasına ötürülən hər lambda anonim sinif nümunəsi yaradır. Inline funksiyalar üçün lambda obyekt yaratmadan çağırış yerində yerləşdirilir. Tutmayan (non-capturing) lambdalar sinqlton obyektlərdə keşlənir.
Return Kotlin-də fun ilə ən yaxın funksiyaya aid olan keçid operatorudur. Lambda funksiya (fun) deyil, ifadədir. Buna görə də lambda daxilində etiketsiz return xarici əhatə edən funksiyaya qayıdış kimi qəbul edilir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun