Lambda, kompakt bir ifade { argümanlar -> gövde } olarak temsil edilen anonim bir işlevdir. Kotlin'de lambdalar, davranışı yüksek mertebeden işlevlere iletmenin birincil yoludur ve ayrı bir işlev bildirmeden kısa ve öz bir sözdizimi sağlar. Kotlin dokümantasyonuna (2026) göre, tipik projelerdeki yüksek mertebeden işlevlerin %70'inden fazlası lambdalarla çağrılır. Lambda, minimum sözdizimsel gürültüyle işlevsel stilde kod yazmayı sağlar.
Önemli Noktalar
Lambda (lambda ifadesi), bir bildirim yerine bir ifade olarak tanımlanan anonim bir işlevdir. Terim, Alonzo Church'ün lambda hesabından (1936) gelir. Programlamada lambda, bir değer olarak iletilebilen, bir değişkende saklanabilen ve daha sonra çağrılabilen bir kod bloğudur. Kotlin'de lambda her zaman süslü parantezler { } içine alınır, argümanlar -> oku ile gövdeden ayrılır.
Lambda, normal bir işlevden ad ve fun anahtar kelimesinin olmamasıyla ayrılır. Bu, kodu ek bildirimlerle karmaşıklaştırmadan, kullanım noktasında doğrudan davranış bildirilmesine olanak tanır. Kotlin derleyicisi argüman tiplerini bağlamdan çıkarır, bu nedenle birçok durumda tipler atlanabilir. Lambda, işlevsel tip (T) -> R üzerinde sözdizimsel şekerdir: her lambdanın karşılık gelen bir işlevsel tipi vardır.
Kotlin'de lambdaların birincil kullanımı, bunları yüksek mertebeden işlevlere iletmektir. Standart kütüphane her yerde lambdaları kullanır: filter { it > 0 }, map { it.uppercase() }, forEach { println(it) }. Lambdalar ayrıca olay dinleyicileri, geri çağırmalar ve apply ile run aracılığıyla nesne yapılandırıcıları için de kullanılır ve anonim sınıflara kıyasla kodu daha bildirimsel hale getirir.
Kotlin'de bir lambda ifadesinin tam biçimi: { argümanlar -> lambda_gövdesi }. Argümanlar virgülle ayrılarak listelenir, ardından bir ok ve gövde — bir veya daha fazla ifade gelir. Gövde birden çok satır içeriyorsa, son ifade dönüş değeri olur. Bir işlev son argüman olarak bir lambda alıyorsa, çağrı parantezlerinin dışına taşınabilir.
val sum: (Int, Int) -> Int = { a, b -> a + b }
// Bağlamdan çıkarılan tipler
val sumShort = { a: Int, b: Int -> a + b }
// Lambda çağrısı
val result = sum(5, 3) // 8
println(result)
sum değişkeni açık bir işlevsel tip (Int, Int) -> Int ile bildirilir ve { a, b -> a + b } lambdası ile başlatılır. sumShort için tipler lambda içinde belirtilir ve değişken tipi çıkarılır. Her iki varyant da eşdeğerdir. Bir lambdayı çağırmak, normal bir işlevi çağırmaktan farklı değildir — sum(5, 3) sözdizimini kullanarak. Argümansız lambda { body } olarak yazılır, tek argümanla — { it -> it * 2 } veya basitçe { it * 2 }.
Bir lambda tam olarak bir argüman aldığında, Kotlin örtük ad it'i sağlar. Bu, sol tarafta argüman bildirme ihtiyacını ortadan kaldırır. Geliştirici yalnızca lambda gövdesini yazar ve tek parametreye erişmek için it'i kullanır. Bu sözdizimi, it'in geçerli öğeye atıfta bulunduğu koleksiyon işleme zincirlerinde özellikle kullanışlıdır.
val numbers = listOf(1, 2, 3, 4, 5)
// Açık parametre adı
val squaredExplicit = numbers.map { n -> n * n }
// Örtük it
val squared = numbers.map { it * it }
// it ile filtreleme
val even = numbers.filter { it % 2 == 0 }
println(squared) // [1, 4, 9, 16, 25]
Örnekte, map { it * it } n -> bildirmek yerine it'i kullanır. Kotlin, tek bir lambda parametresi için otomatik olarak it atar. Bir lambda iki veya daha fazla argüman alıyorsa, it oluşturulmaz — tüm parametreler açıkça bildirilmelidir. İç içe lambdaların daha iyi okunabilirliği için parametrelere anlamlı adlar vermek ve it'i yalnızca kısa tek satırlık yüklemlerde kullanmak uygundur.
Trailing lambda, son lambda argümanını işlev çağrı parantezlerinin dışına taşımaya izin veren bir Kotlin sözdizimi özelliğidir. Bu, kodun yerleşik dil yapılarına benzemesini sağlar. Lambda tek argümansa, parantezler tamamen atlanabilir. Bu yaklaşım, standart kütüphanede ve DSL'lerde aktif olarak kullanılır.
// Standart çağrı
thread(block = {
println("İş parçacığından merhaba")
})
// Trailing lambda sürümü
thread {
println("İş parçacığından merhaba")
}
// trailing lambda ile tekrarla
repeat(3) { index ->
println("Yineleme $index")
}
// çok satırlı lambda ile çalıştır
val config = run {
val host = "localhost"
val port = 8080
"$host:$port"
}
thread işlevi son argüman olarak bir Runnable alır. Trailing lambda sayesinde lambda parantezlerin dışında iletilebilir ve görsel olarak bir kod bloğuna benzer. repeat işlevi bir yineleme sayısı ve bir indeksli lambda alır. run, çok satırlı bir lambdanın son ifade tarafından döndürülen bir değeri hesapladığı yüksek mertebeden bir işlev örneğidir. run() etrafındaki parantezler, lambda tek argümansa atlanabilir.
Değişken yakalama (closure), bir lambdanın dış kapsamda bildirilen değişkenlere erişme yeteneğidir. Kotlin'de lambda, var değişkenlerini okuyup değiştirebilir ve çevreleyen bağlamdan val değişkenlerini okuyabilir. Yakalanan değişkenler, yaşam döngüleri boyunca lambdayla birlikte depolanır ve durum içeren işlevler oluşturulmasını sağlar.
fun makeCounter(): () -> Int {
var count = 0
return {
count++ // yakalama sayısı
}
}
fun main() {
val counter = makeCounter()
println(counter()) // 0
println(counter()) // 1
println(counter()) // 2
}
makeCounter işlevi yerel bir count değişkeni bildirir ve bir lambda { count++ } döndürür. makeCounter yürütmeyi tamamlamış olmasına rağmen, döndürülen lambda kapanış yoluyla count'a bir referans tutar. counter()'a yapılan her çağrı, geçerli değeri artırır ve döndürür. Kapanış mekanizması, currying, işlev fabrikaları ve ezberlemenin temelini oluşturur. Değişebilir değişkenleri yakalamanın eşzamanlı yürütmede beklenmeyen davranışlara yol açabileceğini unutmamak önemlidir.
Sık Sorulan Sorular
Lambda koşulsuz return'ü desteklemez — etiketsiz return, kontrolü dış işleve geri verir. Bir lambdadan çıkmak için return@label kullanın; burada label, lambdanın iletildiği yüksek mertebeden işlevin adıdır.
Anonim işlev fun(a: Int): Int { return a * 2 } olarak yazılır ve etiketsiz return'ü destekler. Lambda { a -> a * 2 } sözdizimde daha kısadır ancak erken çıkış için return@label gerektirir.
Lambda argüman almıyorsa, ok atlanır: { body() }. Bir argüman alıyor ancak kullanmıyorsa, parametreyi yok saymak için alt çizgiyle { _ -> body() } yazın.
Evet, satır içi olmayan bir işleve iletilen her lambda bir anonim sınıf örneği oluşturur. Satır içi işlevler için lambda, nesne oluşturmadan çağrı noktasında satır içine alınır. Yakalamayan lambdalar, tekil nesneler olarak önbelleğe alınır.
Kotlin'de return, fun ile bildirilen en yakın işleve ait bir atlama operatörüdür. Lambda bir işlev (fun) değil, bir ifadedir. Bu nedenle, etiketsiz bir lambda içindeki return, dışarıdaki kapsayıcı işlevden dönüş olarak kabul edilir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun