Kotlin’in Kapsamlı ve Yüksek Dereceli Fonksiyonları

Nasıl kullanılacağını değil nasıl oluşturulacağını öğrenin

Kotlin kullanıyorsanız, aşağıdaki gibi bir tablo görmüş olmalısınız:

Şimdilik tablonun ne dediğini unutun. Tabloyu ezberlemeyin. Aslında hiç bir şeyi ezberlemeyin. Mantığını öğrenin. Temiz bir sayfa ile başlayalım.

Feragatname: Bu uzun bir makale olacak (çaba gerektiren bir şeye hakim olmak). Makaleyi bölümlere ayırıp aralar ekleyeceğim, bir mola başlığı gördüğünüzde bir mola vereceğim.

Bir mola verin.

Web’de, kapsam işlevinin ne yaptığını ve nasıl kullanılacağını açıklayan pek çok makale var. Bu makale bir adım daha ileri götürüyor. Sadece ne yaptıklarını anlamayacağız, aynı zamanda kavramın ustalığını da öğreneceğiz.

Ustalar ne yapar? 

Bir usta, temelleri açık olan ve yalnızca nasıl kullanılacağını değil, nasıl bir şeyler yaratacağını da bilir.

2 basit ve kolay kavramı anlamanız gerekiyor ve Üstat olma yolunda olacaksınız.

  1. Uzatma fonksiyonları
  2. Yüksek Mertebeden Fonksiyon ve Lambda

Bu iki kavramın neden kapsamlı işlevlerle ilgili olduğunu merak ediyorsanız (bırakın, uygulayın, çalıştırın, vb.) ! Yakında tanıyacaksın. Burada konuları hızlıca gözden geçireceğiz. Bu iki kavramı kullanmadıysanız, resmi belge ve daha fazla makale okumanızı tavsiye ederim.

Uzatma fonksiyonları

Yeterince resmi doküman var. Kotlin böyle dekoratör olarak sınıf veya kullanım tasarım desenleri devralmak zorunda kalmadan yeni işlevselliği ile bir sınıf genişletmek için yeteneği sağlar.

Kısacası, orijinal kodu değiştirmeden sınıfta yeni bir işlev tanımlayabilir ve işlevi çağırmak için o sınıfın örneğini kullanabilirsiniz. Sınıfın kaynak koduna bile erişmeniz gerekmez.

Sözdizimi:

fun AnyClass.yourNewFunction(optionalParamIfNeeded : Type) {
    
   // do your magic here and use the instance of AnyClass as `this`
}

StringSınıfta değeri dönüştürmek için bir işlev istediğinizi varsayalım camelcase. Bir tanımlayabilirsiniz function:

fun String.toCamelCase() { 
// some magic, the instance of String is available as `this`
return camelCased;
}fun String.toCamelCase() {
this.substring(1) // referring the caller as thisreturn camelCased;
}

Yüksek Mertebeden Fonksiyon ve Lambda

Buradaki resmi belgelere göre , üst düzey bir işlev, işlevleri parametre olarak alan ya da bir işlev döndüren bir işlevdir. Bir örnek görelim:

fun doSomething(block: () -> Unit) {

}

doSomething() -> Unitparametre almayan ve Birimi döndüren bir işlevi kabul eder . Kotlin’de hiçbir boşluk kavramı yoktur, eğer bir işlev hiçbir şey döndürmezse, Birim döndürür (derleyici sizin için return ifadesini ekler). Bu fonksiyon parametre içerisinde gereklidir ve parametre adı, blockistediğiniz şeyi, hatta xyz olarak adlandırabilirsiniz.

fun doSomething(xyz: () -> Unit) { 
    // xyz parametre adıdır.
}

doSomethingParametre işlevini nasıl çağırdı dersiniz? Sözdizimi çok basittir:

fun doSomething(xyz: () -> Unit) {
    xyz() // normal bir işlev gibi çağırın
}

Cevap normal bir fonksiyon gibi çağırmaktır.

fun  doSomething (block: () -> Unit) { 
    block () // normal bir işlev gibi çağırın 
}

Bir mola verin.

Daha üst düzey bir fonksiyonun başka bir örneğini görelim:

fun doSomething(block: () -> String) {
    val someString:String = block()  // parametre işlevi, String döndürür 
}

Bu sefer, parameterfunctiongeri dönüşler String‘e.

fun doSomething(block: (i:Int) -> String) { 
    // parametre işlemi dizi döndürür.
    val someString:String = block(1)  
}

Bu kez parameterfunctionbir Int kabul eder ve String döndürür.

fun doSomething (block: () -> String): String { 
    return block () // parametre işlevi String döndürür. 
}

doSomething parametresi olmayan ve birimi döndüren bir işlev istiyor.

doSomethingBir işlevi çağırmanın ve iletmenin birkaç yolu vardır.

Yol 1 – Yapıya uyan mevcut bir işlevi geçin

Diyelim ki bir fonksiyonumuz var:

fun randomFunction(){ println("Ben rasgele fonksiyonum") }

Burada rastgele işlev hiçbir parametre kabul etmez ve hiçbir şey döndürmez (yapı, istediklerimizle eşleşir) doSomething)

Biz arayabiliriz:

doSomething(::randomFunction)

Burada doSomethingfonksiyon çağırıyoruz ve randomFunctionparametre olarak geçiyoruz . Sözdizimi ::bir işlevi belirtmektir

fun randomFunction(){ println("I am random") }
fun doSomething(block: () -> Unit) {
   block() // "Rasgele olduğum" yazacaktır 
}
doSomething(::randomFunction)

Parametreleri ile geçirilen işlevi çağırın

Diyelim ki functionkabul etti parameters, onu çağırmak diğer işlevlerden farklı değil:

fun randomFunction(){ 
  println("Ben rastgeleyim") 
}

fun doSomething(block: (i:Int) -> Unit) {

}
// randomFunction Int kabul etmez olarak ❌ derlemek olmaz

IntdoSomething(::randomFunction)

2. Yol – Adsız bir işlevi geçin

fun doSomething(block: (i:Int) -> Unit) {}

Aşağıdaki gibi adsız bir işlevi iletebiliriz:

doSomething (fun(x:Int){
    
})

Dikkat edin, isimsiz bir fonksiyon yarattık ve parametre olarak geçtik. Çağrıldıysak block(99)doSomethinggeçilen fonksiyonumuz x değeri 99 ile çağrılır.

Bir mola verin.

Yol 3 – İşlev türünü genişleten bir sınıf oluşturun ve sınıfınızın örneğini geçin. En iyi kısım.

Örnek 1.

interface CustomFunctionType : () -> Unit {
    override fun invoke()
}

Burada interfacebir functiontür genişleten bir tane yarattık . Bunun tanımı functionhayır kabul parameteredip geri dönmesidir Unit.

Yukarıdaki tanım bir işleve sahip olmakla eşittir:

fun customFunction() {}

Aradaki fark, CustomFunctionTypeçalışma zamanında aşağıdaki gibi örnekler oluşturabilir ve uygulama sağlayabiliriz:

// Burada anonim bir sınıf yaratıyoruz 
val dynamic = object : CustomFunctionType{
    override fun invoke() {
      // sihirinizi burada yapın  expekto patronam :)
    }
}

Benzer bir imza işlevi bekleyen bir işleve sahipsek, yukarıda yarattığımız nesneyi geçebiliriz.

fun doSomething(block: () -> Unit) {
   block() // "Rastgele biriyim" 
}
doSomething(dynamic)

Bu ilk bakışta biraz zor görünebilir. Mesele şu ki, parametre ve dönüş türünü içeren imzayla bir işlev türünü genişleten bir arabirim / sınıf oluşturabiliriz, örneğin ()->Unitbu sınıf / arabirim örneğini işlev imzasının eşleştiği bir parametre olarak geçirebiliriz.

Örnek 2

interface CustomFunctionType : (Int) -> Unit {
    override fun invoke(i:Int)
}

Burada, fonksiyon tipini genişleten başka bir arayüz oluşturduk. Bu işlevin tanımı: int parametresini kabul eder ve hiçbir şey döndürmez.

Örnek 3

interface CustomFunctionType : (Int, Int) -> String {
    override fun invoke(i:Int, j:Int):String
}

Bu, iki Ints kabul eden ve bir String döndüren işleve eşdeğerdir.

Bonus puanı

Beyninin tüm vızıltı vızıltı gidiyor sanırım. Bildiğimiz gibi, yüksek dereceli fonksiyonlar bir değişkene de atanabilir. İşte bir örnek:

fun doSum(i:Int, j:Int):Int{ 
  return i + j 
}
val sum: (Int, Int) -> Int = ::doSum

Burada toplam tür, functionTypeiki ints parametresini kabul eder ve bir Int döndürür. doSumReferans ile fonksiyon atadık::

Şimdi arayabiliriz

sum(1, 1) // equivalent to doSum(1,1)

Bir mola verin.

Yol 4 – Lambda dünyasına girin

Yukarıda gördüğümüz gibi, fonksiyon tipini genişletebilir ve sınıfınızın örneğini geçebiliriz. Kotlin de aynı şekilde kısa bir sözdizimine sahip. Bu bir lambda. FunctionType’ın beklendiği yerde lambda kullanabiliriz. Sözdizimi küme parantezleridir, bunu gövde takip eder.

val sum: (Int, Int) -> Int = {x: Int, y: Int -> x + y}

Sağ taraf bir lambdadır, çünkü kotlinde Type çıkarımını biliyoruz, parametre tiplerini ihmal edebiliriz.

val  sum: (Int, Int) -> Int = {x, y -> x + y}

FunctionType’ın beklendiği yerde lambda kullanabileceğimizi biliyoruz. Bir işlevi işlev parametreleri olarak kullandığımız bir lambda kullanabileceğimiz anlamına gelir. Aynı örneği görelim:

fun  doSomething (blok: () -> Birim) { 

}

Yine, doSomethingbir fonksiyon gerekli ve az önce burada bir lambda kullanabileceğimizi belirttik. Bu işlev hiçbir parametreyi kabul etmiyor ve hiçbir şey döndürmüyor (Birim anlamına gelir), İşte lambda ile bir arama

doSomething({})

Evet, bu kadar basit.

Lambda ile parametreleri nasıl kabul ederiz? Yine çok basit, parametre adını yazabiliriz, ardından yazın.

fun doSomething(block: (i:Int, j:Int) -> Unit) {
}
// lambda ile çağrı 
doSomething({x:int, y:Int -> })

Ama bir lambdadan nasıl döneceğiz? Bildiğimiz gibi Kotlin akıllıdır. Lambda’nın son satırı, geri dönüş olarak çıkar ve tür, beklenen türle eşleşmelidir. Örnek:

fun doSomething(block: (i:Int, j:Int) -> String) {
}
// lambda ile çağırın
doSomething({x:int, y:Int -> 
// burada size özel kodları yazabilirsiniz.
"TheStringToReturn"
})

Yukarıdaki örnekte, TheStringToReturnişlev türü iki Ints kabul eden ve bir String döndüren bir şey beklediğinden geri dönüyoruz . Tabii ki, bu Kotlin ve ayrıntılı olmamıza gerek yok. Parametre tipini atlayabiliriz

doSomething({x, y -> 
// burada size özel kodları yazabilirsiniz.
})

Özel Bir Lambda Sözdizimi:

Aradığınız işlev bir lambdayı kabul ederse (işlev türü), işlev çağrısından sonra lambda yazabilirsiniz. İlk bakışta garip görünüyor ama kısa bir sözdizimi. Yukarıdaki lambda çağrısını şu şekilde yazabiliriz:

doSomething () {x, y -> 
  // burada biraz sihir yapın 
}

Lambda Sözdizimi: Özel Bir – Bir numara daha

Başka bir parametre yoksa ve sadece lambda varsa, küme parantezlerini de ihmal edebiliriz. Böylece yukarıdaki örnek olur:

doSomething {x, y -> 
   // burada biraz sihir yapın 
}

Evet, bu yasal ve gerçekten kısa.

Lambda Sözdizimi: Özel Bir Son Numara

Eğer lambdada sadece bir argüman varsa, adı da ihmal edebilirsiniz. Varsayılan ad it,Evet, lambda içindeki parametrelere erişebilirsiniz.it

İşte bir örnek:

fun doSomething(block: (i:Int) -> String) { 
  block(5)
}
doSomething{"Merhaba, iletilen tek parametrenin değeri : $it"}

Yukarıdaki kod parçası, doSomethingbir işlev türünü kabul eden işlev çağırıyor . Kotlin’in sunduğu en kısa sözdizimine sahip bir lambda ifadesi kullandık. Kıvırcık parantez kullanmadık ve lambda parametre adını kullanmadık çünkü yalnızca bir tane var. Buna atıfta bulunuyoruz $it. Lambda lambda’nın son satırı olan bir Dize döndürüyor. Return ifadesine gerek yoktur.

Aslında lamda ile çağırmak da sihir değil. Kotlin tipi bir anonim sınıfını oluşturur FunctionXX.Nazik çekFunctions.kt in package kotlin.jvm.functions

Bir mola verin.

Alıcı Tipi ve Lambda

Kapsamlı fonksiyonlara geçmeden önce let, apply, also etc.son kavramı anlamamız gerekir.Receiver Type

Artık Uzatma fonksiyonu ve Fonksiyon Tipi parametrelerini biliyoruz, Alıcı Tipinin bu bağlamda ikisinin bir kombinasyonu olduğunu düşünün. Param fonksiyon tipini extension fonksiyonu sözdizimi ile tanımlayabiliriz:

fun  doSomething (block: String. () -> Unit) { 

}

Yukarıdaki örnekte, String.işlev türü parametresinden önce kullandık . Yeni sınıfın functionanonim bir uzantısı haline geldiğini Stringve Stringbu functiontürü çağırmak için bir örneğinin gerekli olduğunu söylüyor . İşte bir örnek:

fun doSomething(block: String.() -> Unit) {
  block() 
  // ❌ "asd" Stringinin bir uzantısı olduğundan izin verilmez 
  .block()
  // ✅ çağırmak için String örneğini kullanıyoruz 
}
// en kısa sözdizimi 
doSomething {
 this.substring(1) 
 // bu, String örneğine atıfta bulunuyor, bu durumda asd
}

Yukarıdaki örnekte String alıcı tipi ve işlev tipi parametrenin kullanımını gördük. String sınıfında anonim bir uzantı işlevi yarattı. Fonksiyon, param ismine atandı ve sadece bu paragrafa erişebildiğimiz yer olarak adlandırılabilir. block.Fakat ya Alıcı tipini VEYA dönüş tipini kodlamak istemezsek. Evet, tahmin edebilirsin.

Jenerikli Alıcı Tipi

Kotlin ve Java’daki jenerikler, derleme zamanı türleridir, ancak şaşırtıcıdırlar ve derleyici, çalışma zamanı yanılsaması sağlamada olağanüstü bir iş çıkarır. Jenerikler ile ilgili detaylar bu makalenin kapsamı dışındadır. İşte resmi dokümanlar ve birkaç blog okumanızı öneriyorum. Jenerik’i çalışırken görelim:

fun<R> doSomething(block: String.(i: Int) -> R) {
    println("Gaurav".block(1))
}

Bu kez, fonksiyon tipi parametremizin dönüş türünde Genel + Alıcı türünü kullandık. İşlevi <Type>aşağıdaki gibi çağırabiliriz :

doSomething <Int> { 
  // burada bir şeyler yap 
  100 
}

Yukarıdaki çağrı, <Int>derleyicinin bir fonksiyon türü döndüren Int. Yukarıdaki lambda 100 döndürüyor.

doSomething <String> { 
  // burada bir şeyler yap 
  "Maaş aynıyken her boka zam gelmesi falan." 
}

Şimdi, String kullanıyoruz ve bir String döndürüyoruz. Unutma, Kotlin akıllıdır ve türünü çıkartabilir. Neden ilan ettin? Kotlin sizin için lambda’nın son ifadesinden dönüş türünü çıkartabilir:

doSomething { 
  // burada bir şeyler yap 
  "Al beni zaman, biraz kırgınım şu dünyaya." 
}

Yukarıdaki çağrı <String> ile çağrıya eşdeğerdir.

Benzer şekilde, Jenerik’i bir alıcı türüyle kullanabiliriz:

fun<T,R> doSomething(t:T, block: T.() -> R) {
    println(t.block())
}

Burada, fonksiyon tipini jenerik bir alıcı tipiyle ilan ettik, bu durumda arayan kişi buradaki tipleri tanımlayacaktır. İşte buna şöyle diyoruz:

doSomething<String, Int>("Şanışer") {
    this.substring(1)
    "from inside"
    1
}

Açıkça belirttiğimiz gibi, arayanlar String türünde ve return türü Int türündedir. Caller tipinde bir örnek iletmeliyiz (bu durumda String). Aksi halde, işlev doSomethingtürü çağırmaz, çünkü Tarayan tarafından tanımlanan türün bir örneğine ihtiyaç duyar . Evet, türleri tekrar atlayabiliriz ve derleyici bizim için çıkartabilir.

doSomething("Şanışer") {
    this.substring(1)
    "from inside"
    1
}

Yukarıdaki işlev çağrısı <String, Int> kullanmaya eşdeğerdir

Alıcı Tipi ile Generic’in son örneği:

fun<T,R> T.doSomething(block: T.() -> R) {
    println(block())
}

Beyniniz mi yandı? Lütfen devam edin. Pes etmeyin. Mükemmel zevk alacaksınız.

Burada, doSomethingGeneric TT.doSomething) ile bir uzatma işlevi olarak tanımlanır, bu her arayanın bir uzatma işlevi olduğu anlamına gelir. Evet, kelimenin tam anlamıyla her örnek, bir üye işlevidir diyebilir.

İşlev türü aynı zamanda T (T.() -> R) türünde adsız bir uzantı işlevidir , bu da her sınıfın her örneği anlamına gelir.

block()Yukarıdaki örnekte aramak için neden bir T örneğine ihtiyacımız yok ? Cevap aynı doSomethingzamanda bir uzatma işlevidir ve blockaynı zamanda bir uzatma işlevidir. Dolaylı olarak, bunlar T tipinin üye işlevleridir ve aynı sınıfın iki üye işlevi birbirlerini doğrudan VEYA thisaşağıda gösterildiği gibi anahtar sözcükle çağırabilir.

fun<T,R> T.doSomething(block: T.() -> R) {
    println(this.block())
}

Beyniniz mi yandı? Lütfen devam edin. Pes etmeyin. Mükemmel zevk alacaksınız.

Burada, doSomethingGeneric TT.doSomething) ile bir uzatma işlevi olarak tanımlanır, bu her arayanın bir uzatma işlevi olduğu anlamına gelir. Evet, kelimenin tam anlamıyla her örnek, bir üye işlevidir diyebilir.

İşlev türü aynı zamanda T (T.() -> R) türünde adsız bir uzantı işlevidir , bu da her sınıfın her örneği anlamına gelir.

block()Yukarıdaki örnekte aramak için neden bir T örneğine ihtiyacımız yok ? Cevap aynı doSomethingzamanda bir uzatma işlevidir ve blockaynı zamanda bir uzatma işlevidir. Dolaylı olarak, bunlar T tipinin üye işlevleridir ve aynı sınıftaki iki üye işlevi birbirlerini doğrudan VEYA thisaşağıda gösterildiği gibi anahtar sözcükle çağırabilir.

Mola verin ve özeti gözden geçirin.

Sonunda, Kotlin’in sunduğu kapsam işlevlerine geçelim .

Veyahutta bir süre bekleyelim.

Bazı örnekler oluşturmak ve size daha önce okuduklarımızın gücünü göstermek istiyorum.

fun <T> T.callMyAnonymousLambda (blok: (T) -> Unit) { 
   blok (this) 
}

Yukarıdaki kod parçasında, Generics ile bir uzatma işlevi ilan ettik. Arayan ile aynı tipte bir parametreye sahip olan ve hiçbir şey döndürmeyen bir fonksiyon tipi parametre kabul eder (Birim).

block(this)lambda’yı çağırmak için kullanılır, çünkü T parametresine ihtiyaç duyar thisve işlev callMyAnonymousLambdaçağrıcısına <T> den başvurur. Yukarıdaki işlevi çağıran örnek:

"Şanışer". callMyAnonymousLambda {name -> 
    println ("Benim adım $ name") 
}

Şimdi T olur Stringve şu şekilde geçirilen lambdabir parametreye Stringsahiptir. name

Hatırlamak. Eğer parametertek parametrede açık bir isim vermezsek lambda, kullanabiliriz.it

"Şanışer". callMyAnonymousLambda { 
         println ("Benim adım $ it") 
}

Ve Kotlinde let‘e benzeyen kendi fonksiyonumuzu yarattık.

İşte let fonksiyon kodu:

fun <T, R> T.let(block: (T) -> R): R {
    return block(this)
}

letile her sınıfa genişletme işlevi olarak tanımlanır Generic T. Arayan olur Tve geri dönüş tipi açıkça ilan edilebilir VEYA derleyici tarafından çıkarılabilir. function-typeParametre blocktürü bir parametre kabul T(bizim durumumuzda arayanın) ve getiri R. Dönen fonksiyonun bilgisi letde R.letyoktur, Rbu yüzden blockgeri dönmek için kullanır .R

"Niximera". let {name-> 
    println ("Benim adım $ name") 
}

veya

"Niximera". let {name-> 
    println ("Benim adım $ name") 
}

let bir uzantı işlevidir ve lambda bir parametreye sahiptir (varsayılan addır) ve lambda’nın son deyimini döndürür çünkü let işlevleri returns block(this)

Başka bir özel işlev oluşturalım:

fun <T> T.callExtensionLambdaAndReturnSelf (blok: T. () -> Unit) {
block ()
}

Burada, callExtensionLambdaAndReturnSelfile tanımlanır Generics <T>, böylece arayan Tburada olur . function-typeHayır kabul eden parameterve hiçbir şey döndürmeyen anonim bir uzantıyı kabul eder . Bizim özel functionde hiçbir şey döndürmez ( Unit)

block()çünkü herhangi bir nesneye olmadan denir callExtensionLambda_AndReturnSelfve blockher iki Onlar aleni hiçbir atıfta gerekmez tip T. uzatma üyeleridir. this.block()Aynı anlama geldiğini de kullanabilirsiniz .

Ve apply‘e benzeyen kendi fonksiyonumuzu yarattık.

İşte uygulama fonksiyon kodu:

fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

İşte uygulamak her tür <T> ve fonksiyon tipi parametre üzerinde bir uzantısı işlevi türüne anonim uzatma fonksiyonu da olduğu <T> işlev çağrıları uygulamak blockiçsel ile thiso arayanı dönüyor referansthis

İşte bir örnek:

class Workshop(val car:Car){}
workshop = Workshop(Ferrari())
workshop.apply<Workshop> {  }
veya
workshop.apply{ 
// burada biraz sihir yapın
}

Ayrıca

fun <T> T.also (blok: (T) -> Birim): T { 
    block (this) 
    return this 
}

alsoFonksiyonu da birlikte bir uzatma fonksiyonudur Generic <T>ve tip bir parametre içeren bir fonksiyonu tipi parametre kabul Tarayan ile aynı. Uygula işlevi arayanın türünü döndürür. itLambda’nın arkasındaki sebep , lambda çağrısı yapmak block(this),istediğiniz her şeyi adlandırmakta özgürsünüz.

RUN!

eğlence <T, R> T.run (blok: T. () -> R): R { 
return blok ()
}

Gördüğümüz gibi run, işlev <T> ile Generics ile tanımlanmış bir uzatma işlevidir, bu nedenle herhangi bir arayan, onu üye işlevi gibi çağırabilir ve aynı zamanda T türünde adsız bir uzantı olan bir lambda kabul eder. lambda. Arayana thisbir uzantı işlevi olduğu için erişiriz.

With

with(receiver: T, block: T.() -> R): R {
    return receiver.block()
}

Burada bir uzantı işlevi değil, işlev türü parametresidir. Bu sefer T parametresini parametre olarak geçiyoruz receiverve blockDinlenme hepsini aramak için kullanıyoruz .

fonksiyonu, lambda içine bakın, geri dönün

Ama hangisini kullanmalı?

Bu makalede, kapsam dahilindeki içsel ve temelleri öğretmek amaçlanmıştır functionsfunctionsİlk bakışta kafa karıştırıcı bir görünüm inkâr edilemez . Projenizde ne kadar faydalı bulursanız kullanın, ancak bazı kullanım örneklerini paylaşmama izin verin:

applygenellikle nesneyi ve arayan nesneyle ilgilendiğiniz yeri dönüş türü olarak kullanmak için kullanılır (isteğe bağlı). Örneğin

dialog.<strong>apply</strong> { 
  setOkButton("TAMAM")
  setCancelButton("VAZGEÇ")
}

letkapsamını değiştirmek ve lambda sonucu ile ilgilendiğimizde kullanılır. NULL olabilecek tipleri ile gerçekten iyi gidiyor. Örneğin

fun doMagic(car:Car?) {  
  car?.<strong>let</strong> {
    it.start() 
  }
}

runİki değişkeni vardır, 1 sadece kapsamı değiştirmek için kullanılır, böylece değişkenlerinizle oynayabilir ve bir şeyler döndürebilirsiniz. Diğer runarayanın alıcı tür parametresi ile uzatma fonksiyonu olarak tanımlanır.

alsoİşlevsel çağrıları zincirlemek için anlamsal olarak kullanılabilir. Örneğin

car.also {// sihir yapın} .also {// sihir yapın}

withbenzer kullanılabilecek applybir kullanım örneği atıfta olmadan özelliklerini değiştirmek için thisve dotörneğin

with(car) { 
   model ="Metallica" manu ="And Justice For All..." 
}

Sonuç

Umarım bu makaleden bir şeyler öğrenmişsinizdir. Niyetim sizi bir usta yapmak, böylece yalnızca kapsamlı işlevleri kullanmakla kalmaz, kendiniz de oluşturabilirsiniz. Her şey temellerle ilgili. Gördük extension functionsve function-typeparametreler çok önemli bir rol oynuyor. Kapsamlı fonksiyonlar sadece hayatınızı kolaylaştıracak araçlardır. Herhangi bir tabloyu ezberlemeye gerek yok. Temellerinizi açıklayın ve akıllıca kullanın. Kafanız karışmasın thisve it,her zaman nereden geldiğini ve arkasındaki mantığı anlayın. Teşekkür ederiz efenim..

Comments

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

GIPHY App Key not set. Please check settings

Yükleniyor…

0

Ne düşünüyorsun?

Cloud computing (bulut bilişim); verilerin sanal bir makine olan bulutta depolandığı ve internete bağlı olan bir cihazın her an her yerde bu bilgilere ulaşabildiği bir online depolama hizmetidir. Bulut teknolojisi; depolama alanı, hızlı veri transferi ve yedekleme işlemlerinde maliyetleri düşürmesi açısından oldukça avantajlı bir hizmettir.

Cloud Hosting vs Cloud Server

Ford, Şarj Edilebilir Hibrit ya da Elektrikli aracınızın bataryasının hep dolu kalmasını sağlamak için pek çok pratik yöntem sunuyor. Seçtiğiniz elektrikli araba veya vanın türüne bağlı olarak size sunabileceğimiz çeşitli şarj seçenekleri ve çözümleri var.

Ford Hibrit Araçlar | 2020