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.
- Uzatma fonksiyonları
- 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` }
String
Sı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
, () -> Unit
parametre 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ı, block
istediğiniz şeyi, hatta xyz olarak adlandırabilirsiniz.
fun doSomething(xyz: () -> Unit) { // xyz parametre adıdır. }
doSomething
Parametre 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, parameterfunction
geri 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 parameterfunction
bir 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.
doSomething
Bir 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 doSomething
fonksiyon çağırıyoruz ve randomFunction
parametre 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 function
kabul 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)
, doSomething
geç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 interface
bir function
tür genişleten bir tane yarattık . Bunun tanımı function
hayır kabul parameter
edip 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 ()->Unit
bu 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, functionType
iki ints parametresini kabul eder ve bir Int döndürür. doSum
Referans 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, doSomething
bir 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, TheStringToReturn
iş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ı, doSomething
bir 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 function
anonim bir uzantısı haline geldiğini String
ve String
bu function
tü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 doSomething
türü çağırmaz, çünkü T
arayan 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, doSomething
Generic T
( T.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ı doSomething
zamanda bir uzatma işlevidir ve block
aynı 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 this
aş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, doSomething
Generic T
( T.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ı doSomething
zamanda bir uzatma işlevidir ve block
aynı 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 this
aş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 this
ve 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 String
ve şu şekilde geçirilen lambda
bir parametreye String
sahiptir. name
Hatırlamak. Eğer parameter
tek 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) }
let
ile her sınıfa genişletme işlevi olarak tanımlanır Generic T
. Arayan olur T
ve geri dönüş tipi açıkça ilan edilebilir VEYA derleyici tarafından çıkarılabilir. function-type
Parametre block
türü bir parametre kabul T
(bizim durumumuzda arayanın) ve getiri R
. Dönen fonksiyonun bilgisi let
de R.let
yoktur, R
bu yüzden block
geri 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, callExtensionLambdaAndReturnSelf
ile tanımlanır Generics <T>
, böylece arayan T
burada olur . function-type
Hayır kabul eden parameter
ve hiçbir şey döndürmeyen anonim bir uzantıyı kabul eder . Bizim özel function
de hiçbir şey döndürmez ( Unit
)
block()
çünkü herhangi bir nesneye olmadan denir callExtensionLambda_AndReturnSelf
ve block
her 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 block
içsel ile this
o 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 }
also
Fonksiyonu da birlikte bir uzatma fonksiyonudur Generic <T>
ve tip bir parametre içeren bir fonksiyonu tipi parametre kabul T
arayan ile aynı. Uygula işlevi arayanın türünü döndürür. it
Lambda’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 this
bir 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 receiver
ve block
Dinlenme hepsini aramak için kullanıyoruz .
Ama hangisini kullanmalı?
Bu makalede, kapsam dahilindeki içsel ve temelleri öğretmek amaçlanmıştır functions
. functions
İ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:
apply
genellikle 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Ç") }
let
kapsamı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 run
arayanı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}
with
benzer kullanılabilecek apply
bir kullanım örneği atıfta olmadan özelliklerini değiştirmek için this
ve 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 functions
ve function-type
parametreler ç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 this
ve it,
her zaman nereden geldiğini ve arkasındaki mantığı anlayın. Teşekkür ederiz efenim..
GIPHY App Key not set. Please check settings