Kotlin Bootcamp for Programmers 3: Functions

Bu codelab, Kotlin Bootcamp for Programmers kursunun bir parçasıdır. Bu kurstan en iyi şekilde yararlanmak için codelab'leri sırayla tamamlamanızı öneririz. Bilgi düzeyinize bağlı olarak bazı bölümleri gözden geçirebilirsiniz. Bu kurs, nesne yönelimli bir dil bilen ve Kotlin'i öğrenmek isteyen programcılara yöneliktir.

Giriş

Bu codelab'de bir Kotlin programı oluşturacak ve Kotlin'deki işlevler hakkında bilgi edineceksiniz. Bu işlevler arasında parametreler için varsayılan değerler, filtreler, lambda'lar ve kompakt işlevler yer alır.

Bu kurstaki dersler, tek bir örnek uygulama oluşturmak yerine bilginizi artırmak için tasarlanmıştır ancak birbirlerinden yarı bağımsız oldukları için aşina olduğunuz bölümleri gözden geçirebilirsiniz. Örneklerin çoğu, bunları bir araya getirmek için akvaryum temasını kullanır. Akvaryumun hikayesinin tamamını görmek isterseniz Kotlin Bootcamp for Programmers (Programcılar için Kotlin Temel Eğitim Programı) adlı Udacity kursuna göz atın.

Bilmeniz gerekenler

  • Modern, nesne yönelimli ve statik olarak yazılmış bir programlama dilinin temelleri
  • En az bir dilde sınıflar, yöntemler ve istisna işleme ile programlama
  • IntelliJ IDEA'da Kotlin'in REPL'si (Read-Eval-Print Loop) ile çalışma
  • Türler, operatörler ve döngüler dahil Kotlin'in temelleri

Bu codelab, nesne yönelimli bir dil bilen ve Kotlin hakkında daha fazla bilgi edinmek isteyen programcılara yöneliktir.

Neler öğreneceksiniz?

  • IntelliJ IDEA'da main() işlevi ve bağımsız değişkenleriyle program oluşturma
  • Varsayılan değerleri ve kompakt işlevleri kullanma
  • Listelere filtre uygulama
  • Temel lambda işlevleri ve yüksek sıralı işlevler oluşturma

Yapacaklarınız

  • Bazı kodları denemek için REPL ile çalışın.
  • Temel Kotlin programları oluşturmak için IntelliJ IDEA ile çalışın.

Bu görevde bir Kotlin programı oluşturacak, main() işlevi ve komut satırından programa nasıl bağımsız değişken geçirileceği hakkında bilgi edineceksiniz.

Önceki bir codelab'de REPL'ye girdiğiniz printHello() işlevini hatırlıyor olabilirsiniz:

fun printHello() {
    println ("Hello World")
}

printHello()
⇒ Hello World

İşlevleri fun anahtar kelimesini ve ardından işlevin adını kullanarak tanımlarsınız. Diğer programlama dillerinde olduğu gibi, parantezler () varsa işlev bağımsız değişkenleri içindir. Küme parantezleri {} işlevin kodunu çerçeveler. Bu işlev hiçbir şey döndürmediği için dönüş türü yoktur.

1. adım: Kotlin dosyası oluşturun

  1. IntelliJ IDEA'yı açın.
  2. IntelliJ IDEA'daki soldaki Proje bölmesinde proje dosyalarınızın ve klasörlerinizin listesi gösterilir. Hello Kotlin altında src klasörünü bulup sağ tıklayın. (Önceki codelab'den Hello Kotlin projesini zaten oluşturmuş olmanız gerekir.)
  3. New > Kotlin File / Class (Yeni > Kotlin Dosyası/Sınıfı) seçeneğini belirleyin.
  4. Kind (Tür) seçeneğini File (Dosya) olarak bırakın ve dosyayı Hello (Merhaba) olarak adlandırın.
  5. Tamam'ı tıklayın.

src klasöründe artık Hello.kt adlı bir dosya var.

2. adım: Kod ekleyin ve programınızı çalıştırın

  1. Diğer dillerde olduğu gibi, Kotlin main() işlevi de yürütme için giriş noktasını belirtir. Tüm komut satırı bağımsız değişkenleri, bir dizi dize olarak iletilir.

    Aşağıdaki kodu Hello.kt dosyasına yazın veya yapıştırın:
fun main(args: Array<String>) {
    println("Hello, world!")
}

Önceki printHello() işleviniz gibi bu işlevde de return ifadesi yok. Kotlin'deki her işlev, açıkça belirtilmese bile bir değer döndürür. Bu nedenle, main() işlevi gibi bir işlev, Kotlin'in değer olmadığını belirtme şekli olan kotlin.Unit türünü döndürür.

  1. Programınızı çalıştırmak için main() işlevinin solundaki yeşil üçgeni tıklayın. Menüden Run 'HelloKt' (HelloKt'yi Çalıştır) seçeneğini belirleyin.
  2. IntelliJ IDEA, programı derleyip çalıştırır. Sonuçlar, aşağıda gösterildiği gibi alt kısımdaki bir günlük bölmesinde görünür.

3. adım: main() işlevine bağımsız değişkenler iletin

Programınızı komut satırından değil IntelliJ IDEA'dan çalıştırdığınız için programa yönelik tüm bağımsız değişkenleri biraz farklı şekilde belirtmeniz gerekir.

  1. Run > Edit Configurations'ı (Çalıştır > Yapılandırmaları Düzenle) seçin. Çalıştırma/Hata Ayıklama Yapılandırmaları penceresi açılır.
  2. Program arguments (Program bağımsız değişkenleri) alanına Kotlin! yazın.
  3. Tamam'ı tıklayın.

4. adım: Dize şablonu kullanmak için kodu değiştirin

Dize şablonu, bir dizeye değişken veya ifade ekler ve $, dizenin hangi bölümünün değişken ya da ifade olacağını belirtir. İfade varsa küme parantezleri {} içine alınır.

  1. Hello.kt dosyasında, karşılama mesajını "world" yerine programa iletilen ilk bağımsız değişken olan args[0]'yi kullanacak şekilde değiştirin.
fun main(args: Array<String>) {
    println("Hello, ${args[0]}")
}
  1. Programı çalıştırın. Çıkış, belirttiğiniz bağımsız değişkeni içerir.
⇒ Hello, Kotlin!

Bu görevde, Kotlin'deki neredeyse her şeyin neden bir değeri olduğunu ve bunun neden yararlı olduğunu öğreneceksiniz.

Diğer bazı dillerde, değeri olmayan kod satırları olan ifadeler bulunur. Kotlin'de neredeyse her şey bir ifadedir ve değeri vardır. Bu değer kotlin.Unit olsa bile.

  1. Hello.kt dosyasında, main() içine println() değerini isUnit adlı bir değişkene atayan ve bunu yazdıran bir kod yazın. (println() bir değer döndürmediği için kotlin.Unit döndürür.)
// Will assign kotlin.Unit
val isUnit = println("This is an expression")
println(isUnit)
  1. Programınızı çalıştırın. İlk println(), "This is an expression" dizesini yazdırır. İkinci println(), ilk println() ifadesinin değerini (yani kotlin.Unit) yazdırır.
⇒ This is an expression
kotlin.Unit
  1. val adlı bir değişken tanımlayın ve bunu 10 olarak başlatın.temperature
  2. Aşağıdaki kodda gösterildiği gibi, isHot adlı başka bir val tanımlayın ve if/else ifadesinin dönüş değerini isHot'ye atayın. Bir ifade olduğundan if ifadesinin değerini hemen kullanabilirsiniz.
val temperature = 10
val isHot = if (temperature > 50) true else false
println(isHot)
⇒ false
  1. Bir dize şablonunda ifadenin değerini kullanın. Balığın güvenli olup olmadığını veya çok sıcak olup olmadığını belirlemek için sıcaklığı kontrol eden bir kod ekleyin, ardından programınızı çalıştırın.
val temperature = 10
val message = "The water temperature is ${ if (temperature > 50) "too warm" else "OK" }."
println(message)
⇒ The water temperature is OK.

Bu görevde, Kotlin'deki işlevler ve çok kullanışlı olan when koşullu ifadesi hakkında daha fazla bilgi edineceksiniz.

1. adım: Bazı işlevler oluşturun

Bu adımda, öğrendiklerinizin bir kısmını bir araya getirip farklı türlerde işlevler oluşturacaksınız. Hello.kt dosyasının içeriğini bu yeni kodla değiştirebilirsiniz.

  1. Haftanın rastgele bir gününü almak için randomDay() işlevini çağıran feedTheFish() adlı bir işlev yaz. Balığın o gün yiyeceği için food yazdırmak üzere bir dize şablonu kullanın. Şimdilik balıklar her gün aynı yemi yiyor.
fun feedTheFish() {
    val day = randomDay()
    val food = "pellets"
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}
  1. Bir diziden rastgele bir gün seçip döndürmek için randomDay() işlevini yaz.

nextInt() işlevi, week dizisiyle eşleşmesi için sayıyı Random() ile 0 arasında 6 ile sınırlandıran bir tam sayı sınırı alır.

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
            "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}
  1. Random() ve nextInt() işlevleri java.util.* içinde tanımlanır. Dosyanın en üstüne gerekli içe aktarma işlemini ekleyin:
import java.util.*    // required import
  1. Programınızı çalıştırın ve çıktıyı kontrol edin.
⇒ Today is Tuesday and the fish eat pellets

2. adım: "Ne zaman" ifadesini kullanın

Bunu daha da genişleterek when ifadesini kullanarak farklı günler için farklı yemekler seçmek üzere kodu değiştirin. when ifadesi, diğer programlama dillerindeki switch ifadesine benzer ancak when her dalın sonunda otomatik olarak kesilir. Ayrıca, bir enum'ı kontrol ediyorsanız kodunuzun tüm dalları kapsadığından da emin olur.

  1. Hello.kt dosyasında, fishFood() adlı bir işlev ekleyin. Bu işlev, String olarak bir gün alır ve o gün için balığın yiyeceğini String olarak döndürür. Balığın her gün belirli bir yiyecek alması için when() kullanın. Farklı çıkışları görmek için programınızı birkaç kez çalıştırın.
fun fishFood (day : String) : String {
    var food = ""
    when (day) {
        "Monday" -> food = "flakes"
        "Tuesday" -> food = "pellets"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Saturday" -> food = "lettuce"
        "Sunday" -> food = "plankton"
    }
    return food
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)

    println ("Today is $day and the fish eat $food")
}
⇒ Today is Thursday and the fish eat granules
  1. else kullanarak when ifadesine varsayılan bir dal ekleyin. Test için, programınızda bazen varsayılan değerin alındığından emin olmak üzere Tuesday ve Saturday dallarını kaldırın.

    Varsayılan bir dalın olması, food'nin döndürülmeden önce bir değer almasını sağlar. Bu nedenle, artık başlatılması gerekmez. Kod artık food değişkenine yalnızca bir kez dize atadığından food değişkenini var yerine val ile bildirebilirsiniz.
fun fishFood (day : String) : String {
    val food : String
    when (day) {
        "Monday" -> food = "flakes"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Sunday" -> food = "plankton"
        else -> food = "nothing"
    }
    return food
}
  1. Her ifadenin bir değeri olduğundan bu kodu biraz daha kısa hale getirebilirsiniz. when ifadesinin değerini doğrudan döndürün ve food değişkenini ortadan kaldırın. when ifadesinin değeri, koşulu karşılayan dalın son ifadesinin değeridir.
fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

Programınızın son sürümü aşağıdaki koda benzer.

import java.util.*    // required import

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
        "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}

fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}

Bu görevde, işlevler ve yöntemler için varsayılan değerler hakkında bilgi edineceksiniz. Ayrıca, kodunuzu daha kısa ve okunabilir hale getirebilen ve test için kod yollarının sayısını azaltabilen kısa işlevler hakkında bilgi edinebilirsiniz. Kısa işlevlere tek ifadeli işlevler de denir.

1. adım: Bir parametre için varsayılan değer oluşturun

Kotlin'de bağımsız değişkenleri parametre adına göre iletebilirsiniz. Parametreler için varsayılan değerler de belirtebilirsiniz: Arayan tarafından bir bağımsız değişken sağlanmazsa varsayılan değer kullanılır. Daha sonra yöntemler (üye işlevleri) yazdığınızda, aynı yöntemin çok sayıda aşırı yükleme sürümünü yazmaktan kaçınabilirsiniz.

  1. Hello.kt dosyasında, balığın hızını yazdıran swim() işlevini String parametresiyle birlikte speed adıyla yazın. speed parametresinin varsayılan değeri "fast"'dir.
fun swim(speed: String = "fast") {
   println("swimming $speed")
}
  1. main() işlevinden swim() işlevini üç şekilde çağırın. Öncelikle işlevi varsayılanı kullanarak çağırın. Ardından işlevi çağırın ve speed parametresini ad olmadan iletin, ardından speed parametresini adlandırarak işlevi çağırın.
swim()   // uses default speed
swim("slow")   // positional argument
swim(speed="turtle-like")   // named parameter
⇒ swimming fast
swimming slow
swimming turtle-like

2. adım: Gerekli parametreleri ekleyin

Bir parametre için varsayılan değer belirtilmemişse ilgili bağımsız değişken her zaman iletilmelidir.

  1. Hello.kt dosyasında üç parametre alan bir shouldChangeWater() işlevi yazın: day, temperature ve dirty düzeyi. Su değiştirilmesi gerekiyorsa işlev true değerini döndürür. Bu durum, pazar günüyse, sıcaklık çok yüksekse veya su çok kirlenmişse geçerlidir. Haftanın günü zorunludur ancak varsayılan sıcaklık 22, varsayılan kirlilik düzeyi ise 20'dir.

    Kotlin'de bir dizi if/else if kontrolü gibi davranan, bağımsız bir when ifadesi kullanın.
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        temperature > 30 -> true
        dirty > 30 -> true
        day == "Sunday" ->  true
        else -> false
    }
}
  1. feedTheFish() adlı kişiyi shouldChangeWater() numaradan arayın ve günü belirtin. day parametresinin varsayılan değeri yoktur. Bu nedenle bir bağımsız değişken belirtmeniz gerekir. shouldChangeWater() işlevinin diğer iki parametresinin varsayılan değerleri olduğundan bunlar için bağımsız değişken iletmeniz gerekmez.
fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
    println("Change water: ${shouldChangeWater(day)}")
}
=> Today is Thursday and the fish eat granules
Change water: false

3. adım: Kompakt işlevler oluşturun

Önceki adımda yazdığınız when ifadesi, az miktarda kodda çok fazla mantık içerir. Bu durumu biraz daha ayrıntılı incelemek veya kontrol edilecek koşullar daha karmaşık olduğunda, iyi adlandırılmış bazı yerel değişkenleri kullanabilirsiniz. Ancak Kotlin'de bu işlem kompakt işlevlerle yapılır.

Kısa işlevler veya tek ifadeli işlevler, Kotlin'de yaygın bir kalıptır. Bir işlev tek bir ifadenin sonuçlarını döndürdüğünde, işlevin gövdesini = sembolünden sonra belirtebilir, küme parantezlerini {} ve return sembolünü atlayabilirsiniz.

  1. Hello.kt dosyasında koşulları test etmek için kompakt işlevler ekleyin.
fun isTooHot(temperature: Int) = temperature > 30

fun isDirty(dirty: Int) = dirty > 30

fun isSunday(day: String) = day == "Sunday"
  1. Yeni işlevleri çağırmak için shouldChangeWater() değerini değiştirin.
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        isTooHot(temperature) -> true
        isDirty(dirty) -> true
        isSunday(day) -> true
        else  -> false
    }
}
  1. Programınızı çalıştırın. shouldChangeWater() ile println() işlevinin çıktısı, kompakt işlevleri kullanmaya geçmeden öncekiyle aynı olmalıdır.

Varsayılan değerler

Bir parametrenin varsayılan değeri, değer olmak zorunda değildir. Aşağıdaki kısmi örnekte gösterildiği gibi başka bir işlev olabilir:

fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = getDirtySensorReading()): Boolean {
    ...

Bu görevde, Kotlin'deki filtreler hakkında bilgi edineceksiniz. Filtreler, bir listenin belirli bir koşula göre bir kısmını almanın kullanışlı bir yoludur.

1. adım: Filtre oluşturun

  1. Hello.kt dosyasında, listOf() ile üst düzeyde bir akvaryum süsleri listesi tanımlayın. Hello.kt dosyasının içeriğini değiştirebilirsiniz.
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
  1. Yalnızca "p" harfiyle başlayan süslemeleri yazdıracak bir satır içeren yeni bir main() işlevi oluşturun. Filtre koşulunun kodu küme parantezleri {} içindedir ve it, filtre döngüleri sırasında her öğeyi ifade eder. İfade true değerini döndürürse öğe dahil edilir.
fun main() {
    println( decorations.filter {it[0] == 'p'})
}
  1. Programınızı çalıştırdığınızda Çalıştır penceresinde aşağıdaki çıkışı görürsünüz:
⇒ [pagoda, plastic plant]

2. adım: İstekli ve tembel filtreleri karşılaştırın

Diğer dillerdeki filtreleri biliyorsanız Kotlin'deki filtrelerin eager (istekli) mi yoksa lazy (tembel) mi olduğunu merak edebilirsiniz. Sonuç listesi hemen mi yoksa listeye erişildiğinde mi oluşturulur? Kotlin'de bu işlem, ihtiyacınıza göre gerçekleşir. Varsayılan olarak filter isteklidir ve filtreyi her kullandığınızda bir liste oluşturulur.

Filtreyi tembel hale getirmek için Sequence kullanabilirsiniz. Bu, başlangıçtan sona doğru ilerleyerek her seferinde yalnızca bir öğeye bakabilen bir koleksiyondur. Bu API, tembel bir filtrenin tam olarak ihtiyaç duyduğu API'dir.

  1. Hello.kt dosyasında, filtrelenmiş listeyi eager adlı bir değişkene atamak için kodunuzu değiştirin ve ardından yazdırın.
fun main() {
    val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

    // eager, creates a new list
    val eager = decorations.filter { it [0] == 'p' }
    println("eager: " + eager)
  1. Bu kodun altında, filtreyi Sequence ile asSequence() kullanarak değerlendirin. Diziyi filtered adlı bir değişkene atayın ve yazdırın.
   // lazy, will wait until asked to evaluate
    val filtered = decorations.asSequence().filter { it[0] == 'p' }
    println("filtered: " + filtered)

Filtre sonuçlarını Sequence olarak döndürdüğünüzde filtered değişkeni yeni bir liste tutmaz. Bunun yerine, liste öğelerinin Sequence ve bu öğelere uygulanacak filtre hakkında bilgi tutar. Sequence öğelerine her eriştiğinizde filtre uygulanır ve sonuç size döndürülür.

  1. Diziyi toList() ile List'ya dönüştürerek dizinin değerlendirilmesini zorlayın. Sonucu yazdırın.
    // force evaluation of the lazy list
    val newList = filtered.toList()
    println("new list: " + newList)
  1. Programınızı çalıştırın ve çıktıyı inceleyin.
⇒ eager: [pagoda, plastic plant]
filtered: kotlin.sequences.FilteringSequence@386cc1c4
new list: [pagoda, plastic plant]

Sequence ve tembel değerlendirme ile ilgili işlemleri görselleştirmek için map() işlevini kullanın. map() işlevi, dizideki her öğe üzerinde basit bir dönüşüm gerçekleştirir.

  1. Yukarıdakiyle aynı decorations listesini kullanarak hiçbir şey yapmayan ve yalnızca iletilen öğeyi döndüren map() ile bir dönüşüm yapın. Bir öğeye her erişildiğinde println() ekleyin ve diziyi lazyMap adlı bir değişkene atayın.
    val lazyMap = decorations.asSequence().map {
        println("access: $it")
        it
    }
  1. lazyMap yazdırın, first() kullanarak lazyMap öğesinin ilk öğesini yazdırın ve List'ye dönüştürülmüş lazyMap yazdırın.
    println("lazy: $lazyMap")
    println("-----")
    println("first: ${lazyMap.first()}")
    println("-----")
    println("all: ${lazyMap.toList()}")
  1. Programınızı çalıştırın ve çıktıyı inceleyin. lazyMap yazdırıldığında yalnızca Sequence öğesine referans yazdırılır. İçteki println() öğesi çağrılmaz. İlk öğenin yazdırılması yalnızca ilk öğeye erişir. Sequence öğesini List öğesine dönüştürmek tüm öğelere erişir.
⇒ lazy: kotlin.sequences.TransformingSequence@5ba23b66
-----
access: rock
first: rock
-----
access: rock
access: pagoda
access: plastic plant
access: alligator
access: flowerpot
all: [rock, pagoda, plastic plant, alligator, flowerpot]
  1. Sequence uygulamasından önce orijinal filtreyi kullanarak yeni bir Sequence oluşturun.map Bu sonucu yazdırın.
    val lazyMap2 = decorations.asSequence().filter {it[0] == 'p'}.map {
        println("access: $it")
        it
    }
    println("-----")
    println("filtered: ${ lazyMap2.toList() }")
  1. Programınızı çalıştırın ve ek çıktıyı inceleyin. İlk öğeyi alma işleminde olduğu gibi, içteki println() yalnızca erişilen öğeler için çağrılır.
⇒
-----
access: pagoda
access: plastic plant
filtered: [pagoda, plastic plant]

Bu görevde, Kotlin'deki lambda ifadeleri ve yüksek sıralı işlevler hakkında bilgi edineceksiniz.

Lambda işlevleri

Kotlin, geleneksel adlandırılmış işlevlerin yanı sıra lambda'ları da destekler. Lambda, bir işlev oluşturan ifadedir. Ancak adlandırılmış bir işlev bildirmek yerine adı olmayan bir işlev bildirirsiniz. Bu işlevin faydalı olmasının bir nedeni, lambda ifadesinin artık veri olarak iletilebilmesidir. Diğer dillerde lambda'lar anonim işlevler, işlev değişmezleri veya benzer adlarla anılır.

Yüksek sıralı işlevler

Başka bir işleve lambda geçirerek yüksek sıralı bir işlev oluşturabilirsiniz. Önceki görevde filter adlı bir üst düzey işlev oluşturmuştunuz. Kontrol edilecek koşul olarak filter işlevine aşağıdaki lambda ifadesini ilettiniz:
{it[0] == 'p'}

Benzer şekilde, map de yüksek sıralı bir işlevdir ve kendisine ilettiğiniz lambda, uygulanacak dönüşümdür.

1. adım: Lambda işlevleri hakkında bilgi edinin

  1. Adlandırılmış işlevler gibi, lambda işlevleri de parametre içerebilir. Lambda'larda parametreler (ve gerekirse türleri) işlev oku -> olarak adlandırılan ifadenin soluna yerleştirilir. Yürütülecek kod, işlev okunun sağına gider. Lambda bir değişkene atandıktan sonra, onu tıpkı bir işlev gibi çağırabilirsiniz.

    REPL'yi (Araçlar > Kotlin > Kotlin REPL) kullanarak bu kodu deneyin:
var dirtyLevel = 20
val waterFilter = { dirty : Int -> dirty / 2}
println(waterFilter(dirtyLevel))
⇒ 10

Bu örnekte lambda, Int adlı bir dirty alır ve dirty / 2 döndürür. (Çünkü filtreleme, kiri temizler.)

  1. Kotlin'in işlev türleri için söz dizimi, lambda'lar için söz dizimiyle yakından ilişkilidir. Bir işlevi tutan değişkeni net bir şekilde tanımlamak için şu söz dizimini kullanın:
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }

Kodda şunlar belirtiliyor:

  • waterFilter adlı bir değişken oluşturun.
  • waterFilter, Int alan ve Int döndüren herhangi bir işlev olabilir.
  • waterFilter öğesine bir lambda atayın.
  • Lambda, dirty bağımsız değişkeninin 2'ye bölünmesiyle elde edilen değeri döndürür.

Lambda bağımsız değişkeninin türünü artık belirtmeniz gerekmediğini unutmayın. Tür, tür çıkarımıyla hesaplanır.

2. adım: Yüksek sıralı bir işlev oluşturun

Şimdiye kadar, lambda'larla ilgili örnekler çoğunlukla işlevlere benziyordu. Lambda'ların gerçek gücü, bir işlevin bağımsız değişkeninin başka bir işlev olduğu yüksek sıralı işlevler oluşturmak için kullanılmalarından gelir.

  1. Yüksek sıralı bir fonksiyon yazın. İki bağımsız değişken alan bir işlev olan temel bir örneği burada bulabilirsiniz. İlk bağımsız değişken bir tamsayıdır. İkinci bağımsız değişken, bir tam sayı alan ve tam sayı döndüren bir işlevdir. REPL'de deneyin.
fun updateDirty(dirty: Int, operation: (Int) -> Int): Int {
   return operation(dirty)
}

Kodun gövdesi, ikinci bağımsız değişken olarak iletilen işlevi çağırır ve ilk bağımsız değişkeni bu işlevle birlikte iletir.

  1. Bu işlevi çağırmak için işlevine bir tam sayı ve bir işlev iletin.
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }
println(updateDirty(30, waterFilter))
⇒ 15

İlettiğiniz işlevin lambda olması gerekmez. Bunun yerine normal bir adlandırılmış işlev olabilir. Bağımsız değişkeni normal bir işlev olarak belirtmek için :: operatörünü kullanın. Bu şekilde Kotlin, işlev referansını bağımsız değişken olarak ilettiğinizi, işlevi çağırmaya çalışmadığınızı anlar.

  1. updateDirty()'ya normal bir adlandırılmış işlev geçirmeyi deneyin.
fun increaseDirty( start: Int ) = start + 1

println(updateDirty(15, ::increaseDirty))
⇒ 16
var dirtyLevel = 19;
dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}
println(dirtyLevel)
⇒ 42
  • IntelliJ IDEA'da Kotlin kaynak dosyası oluşturmak için Kotlin projesiyle başlayın.
  • IntelliJ IDEA'da bir programı derleyip çalıştırmak için main() işlevinin yanındaki yeşil üçgeni tıklayın. Çıkış, aşağıdaki günlük penceresinde görünür.
  • IntelliJ IDEA'da, Run > Edit Configurations (Çalıştır > Yapılandırmaları Düzenle) bölümünde main() işlevine iletilecek komut satırı bağımsız değişkenlerini belirtin.
  • Kotlin'deki neredeyse her şeyin bir değeri vardır. Bu bilgiyi kullanarak if veya when değerini ifade ya da dönüş değeri olarak kullanıp kodunuzu daha kısa hale getirebilirsiniz.
  • Varsayılan bağımsız değişkenler, bir işlevin veya yöntemin birden fazla sürümünün kullanılmasını gerektirmez. Örneğin:
    fun swim(speed: String = "fast") { ... }
  • Kısa işlevler veya tek ifadeli işlevler, kodunuzun daha okunabilir olmasını sağlayabilir. Örneğin:
    fun isTooHot(temperature: Int) = temperature > 30
  • Lambda ifadelerini kullanan filtrelerle ilgili bazı temel bilgileri öğrendiniz. Örneğin:
    val beginsWithP = decorations.filter { it [0] == 'p' }
  • Lambda ifadesi, adlandırılmamış bir işlev oluşturan ifadedir. Lambda ifadeleri, küme parantezleri {} arasında tanımlanır.
  • Yüksek sıralı işlevlerde, lambda ifadesi gibi bir işlevi veri olarak başka bir işleve aktarırsınız. Örneğin:
    dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}

Bu derste, özellikle lambda'lar konusunda yeniyseniz öğreneceğiniz çok şey var. Daha sonraki bir derste lambda'lar ve yüksek sıralı işlevler tekrar ele alınır.

Kotlin belgeleri

Bu kurstaki herhangi bir konu hakkında daha fazla bilgi edinmek veya takıldığınız noktaları aşmak için https://kotlinlang.org adresini ziyaret edebilirsiniz.

Kotlin eğitimleri

https://try.kotlinlang.org web sitesinde Kotlin Koans adlı zengin eğitimler, web tabanlı bir yorumlayıcı ve örneklerle birlikte eksiksiz bir referans dokümanı seti yer alır.

Udacity kursu

Bu konuyla ilgili Udacity kursunu görüntülemek için Kotlin Bootcamp for Programmers'a (Programcılar için Kotlin Temel Eğitimi) göz atın.

IntelliJ IDEA

IntelliJ IDEA ile ilgili dokümanları JetBrains web sitesinde bulabilirsiniz.

Bu bölümde, bir eğitmenin yönettiği kurs kapsamında bu codelab'i tamamlayan öğrenciler için olası ödevler listelenmektedir. Eğitmen, aşağıdakileri yapmalıdır:

  • Gerekirse ödev atayın.
  • Öğrencilere ev ödevi ödevlerini nasıl göndereceklerini bildirin.
  • Ödevlere not verin.

Eğitmenler bu önerileri istedikleri kadar kullanabilir ve uygun olduğunu düşündükleri diğer ödevleri verebilirler.

Bu codelab'i kendi başınıza tamamlıyorsanız bilginizi test etmek için bu ödevleri kullanabilirsiniz.

Bu soruları yanıtlayın

1. Soru

contains(element: String) işlevi, element dizesi çağrıldığı dizeyi içeriyorsa true değerini döndürür. Aşağıdaki kodun çıktısı ne olur?

val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

println(decorations.filter {it.contains('p')})

[pagoda, plastic, plant]

[pagoda, plastic plant]

[pagoda, plastic plant, flowerpot]

[rock, alligator]

2. Soru

Aşağıdaki işlev tanımında hangi parametre gereklidir?
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20, numDecorations: Int = 0): Boolean {...}

numDecorations

dirty

day

temperature

3. Soru

Başka bir işleve normal bir adlandırılmış işlev (çağrılmasının sonucu değil) iletebilirsiniz. increaseDirty( start: Int ) = start + 1 değerini updateDirty(dirty: Int, operation: (Int) -> Int) değerine nasıl iletirsiniz?

updateDirty(15, &increaseDirty())

updateDirty(15, increaseDirty())

updateDirty(15, ("increaseDirty()"))

updateDirty(15, ::increaseDirty)

Sonraki derse geçin: 4. Sınıflar ve nesneler

Diğer codelab'lerin bağlantıları da dahil olmak üzere kursa genel bir bakış için "Kotlin Bootcamp for Programmers: Welcome to the course." başlıklı makaleyi inceleyin.