İçeriğe geç
Educora
Orta20 dk5 / 14

Fonksiyonlar ve lambdalar

Kendi fonksiyonlarını yaz: varsayılan değerler ve adlandırılmış argümanlar, tek ifadeli fonksiyonlar, genişletme fonksiyonları, lambdalar ve yüksek mertebeden fonksiyonlar.

Kendini test et
Bu derste öğreneceklerin
  • Parametreleri ve dönüş türü olan bir fonksiyon tanımlamak
  • Varsayılan değerleri, adlandırılmış argümanları ve tek ifadeli fonksiyonları kullanmak
  • Var olan türlere genişletme fonksiyonları eklemek
  • Bir lambda yazmak ve onu yüksek mertebeden bir fonksiyona vermek

Programının on yerinde aynı selamlama metnini oluşturduğunu düşün. Metnin değişmesi gerektiğinde on yeri düzeltmen gerekecek! Fonksiyon, kodu bir kez yazıp ona bir ad vermeni ve istediğin kadar çağırmanı sağlar. Fonksiyonlarla zaten çalıştın: main, println ve repeat birer fonksiyondur. Şimdi kendi fonksiyonlarını oluşturacaksın.

Fonksiyon tanımlamak

Bir fonksiyon fun sözcüğüyle başlar; ardından adı ve parantez içinde parametreleri gelir. Kotlin'de her parametrenin türü mutlaka yazılır: name: String. Parantezden sonra iki nokta ile dönüş türü belirtilir, sonuç da return ile döndürülür. Hiçbir şey döndürmeyen bir fonksiyonun türü Unit'tir ve yazılmayabilir.

Kotlin
fun greet(name: String, greeting: String = "Hello"): String {
    return "$greeting, $name!"
}

fun printLine(length: Int = 10) {
    println("-".repeat(length))
}

fun main() {
    println(greet("Aysel"))
    println(greet("Murad", "Salam"))
    println(greet(greeting = "Hi", name = "Leyla"))
    printLine()
    printLine(5)
}
Beklenen çıktı
Hello, Aysel!
Salam, Murad!
Hi, Leyla!
----------
-----
  • greeting: String = "Hello" bir varsayılan değerdir: çağrıda argüman verilmezse "Hello" kullanılır.
  • greet(greeting = "Hi", name = "Leyla") adlandırılmış argümanlar kullanır: parametre adlarını yazınca sıra önemli olmaz ve kod daha anlaşılır okunur.
  • printLine hiçbir şey döndürmez; türü Unit'tir, yalnızca ekrana yazar.

Tek ifadeli fonksiyonlar

Bir fonksiyonun tüm işi tek bir ifadeyi hesaplamaksa süslü parantezleri ve return'ü atıp ifadeyi = işaretinden sonra yazabilirsin. Dönüş türünü derleyici kendisi çıkarır. if ve when birer ifade olduğu için böyle bir fonksiyonda onlar da kullanılabilir.

Kotlin
fun square(x: Int) = x * x
fun isEven(n: Int) = n % 2 == 0
fun rectangleArea(width: Double, height: Double) = width * height
fun result(score: Int) = if (score >= 50) "passed" else "failed"

fun main() {
    println(square(7))
    println(isEven(10))
    println(rectangleArea(4.0, 2.5))
    println(result(73))
}
Beklenen çıktı
49
true
10.0
passed

Genişletme fonksiyonları

Kotlin'de var olan bir türe, hatta String ya da Int gibi standart bir türe yeni bir fonksiyon “ekleyebilirsin”. Bunun için fonksiyon adından önce tür ve nokta yazılır: fun String.shout(). Fonksiyonun içinde this değerin kendisidir. Böyle bir fonksiyon sonra sıradan bir metot gibi çağrılır: "salam".shout().

Kotlin
fun String.shout() = uppercase() + "!"
fun Int.isEven() = this % 2 == 0
fun Double.toManat() = "$this AZN"

fun main() {
    println("salam".shout())
    println(8.isEven())
    println(12.5.toManat())
}
Beklenen çıktı
SALAM!
true
12.5 AZN

Lambdalar

Lambda, süslü parantez içinde yazılan adsız, kısa bir fonksiyondur: { x: Int -> x * 2 }. Okun solunda parametreler, sağında gövde bulunur; son ifadenin değeri lambdanın sonucudur. Bir lambdayı değişkene atayabilirsin; türü şöyle yazılır: (Int) -> Int, yani “Int alır, Int döndürür”. Lambdanın tek parametresi varsa onu yazmayıp gövdede it adıyla kullanabilirsin.

Kotlin
fun main() {
    val double = { x: Int -> x * 2 }
    val add: (Int, Int) -> Int = { a, b -> a + b }
    val greet: (String) -> String = { "Hello, $it!" }
    println(double(21))
    println(add(3, 4))
    println(greet("Elvin"))
}
Beklenen çıktı
42
7
Hello, Elvin!

Yüksek mertebeden fonksiyonlar

Parametre olarak başka bir fonksiyon alan (ya da fonksiyon döndüren) fonksiyona yüksek mertebeden fonksiyon denir. Aşağıda applyTwice kendisine verilen işlemi iki kez uygular. Lambda son argümansa parantezin dışına yazılabilir. Hazır bir fonksiyon ise :: ile verilebilir: ::multiply.

Kotlin
fun applyTwice(x: Int, f: (Int) -> Int): Int = f(f(x))

fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
    return operation(a, b)
}

fun multiply(a: Int, b: Int) = a * b

fun main() {
    println(applyTwice(3) { it + 10 })
    println(applyTwice(5) { it * it })
    println(calculate(8, 2) { a, b -> a - b })
    println(calculate(8, 2, ::multiply))
}
Beklenen çıktı
23
625
6
16
applyTwice(5) { it * it }: önce 5 · 5 = 25, sonra 25 · 25 = 625.

Standart kütüphane lambda alan fonksiyonlarla doludur. Geçen dersteki repeat(3) { ... } bile yüksek mertebeden bir fonksiyondur! Karakter dizilerinde count koşula uyan karakterleri sayar, filter ise yalnızca onları tutar:

Kotlin
fun main() {
    val word = "Programming"
    println(word.count { it == 'm' })
    println(word.filter { it !in "aeiou" })
    println(word.any { it.isDigit() })
    repeat(2) { i -> println("Attempt ${i + 1}") }
}
Beklenen çıktı
2
Prgrmmng
false
Attempt 1
Attempt 2
repeat, lambdaya 0'dan başlayarak adım numarasını verir.

Önemli noktalar

  • Fonksiyon fun ad(parametre: Tür): DönüşTürü { ... } biçiminde yazılır; hiçbir şey döndürmeyen fonksiyonun türü Unit'tir.
  • Varsayılan değerler argümanları isteğe bağlı yapar, adlandırılmış argümanlar ise sıraya bağımlılığı ortadan kaldırır.
  • Tek ifadeli fonksiyon: fun square(x: Int) = x * x.
  • Genişletme fonksiyonu var olan bir türe yeni bir metot ekler: fun String.shout().
  • Lambda adsız bir fonksiyondur: { a, b -> a + b }; tek parametrenin adı it'tir.
  • Yüksek mertebeden fonksiyon başka bir fonksiyonu parametre olarak alır; sondaki lambda parantezin dışına yazılabilir.

Kendini test et

10 soru. Her doğru cevap XP kazandırır.

1 / 10
fun area(w: Int, h: Int = 2) = w * h verildiğinde area(5) nedir?