Kotlin standart funktsiyalarini o'zlashtirish: ishlatish, ishlatish, ruxsat berish va qo'llash

Kotlinning ba'zi standart funktsiyalari shu qadar o'xshashki, ulardan foydalanishni aniq bilmaymiz. Bu erda men ularning farqlarini aniq aniqlashning oddiy usulini va qanday foydalanishni tanlashni taklif qilaman.

Qo'llash funktsiyalari

Men ko'rib chiqadigan funktsiyalar T.run, T.let, T.also va T.apply bilan birgalikda amalga oshiriladi. Men ularni keng qamrovli funktsiyalar deb atayman, chunki men ularning asosiy funktsiyalarini qo'ng'iroq qiluvchining funktsiyasi uchun ichki doirani ta'minlaydigan deb bilaman.

Ko'lamni tasvirlashning eng oddiy usuli bu yugurish funktsiyasi

qiziqarli test () {
    var mood = "Men xafaman"

    ishga tushirish {
        val kayfiyati = "Men baxtliman"
        println (kayfiyat) // Men xursandman
    }
    println (kayfiyat) // Men xafaman
}

Bunda, test funktsiyasida siz alohida doiraga ega bo'lishingiz mumkin, u erda kayfiyat men bosmadan oldin xursandman va u ishlaydigan doirada to'liq bo'ladi.

Ushbu o'lchov funktsiyasining o'zi unchalik foydali emasga o'xshaydi. Ammo shunchaki qamrab olishdan tashqari yana bir yoqimli jihati bor; u biror narsani, ya'ni doiradagi oxirgi ob'ektni qaytaradi.

Shunday qilib, quyida keltirilgan shaffof bo'ladi, biz shou () ni ikkala ko'rinishga ham, uni ikki marta chaqirmasdan ham qo'llashimiz mumkin.

    ishga tushirish {
        if (firstTimeView) introView boshqa normalView
    } .show ()

Qo'llash funktsiyasining 3 atributi

Ko'zda tutilgan funktsiyalarni yanada qiziqarli qilish uchun, ularning xatti-harakatlarini 3 atribut bilan tasniflashga ijozat bering. Men bu sifatlardan ularni bir-biridan ajratish uchun foydalanaman.

1. Oddiy va kengaytma funktsiyasi

Agar T.run bilan boqsak, ikkala vazifa ham bir-biriga o'xshashdir. Quyida xuddi shunday ishlaydi.

bilan (webview.settings) {
    javaScriptEnabled = true
    databaseEnabled = true
}
// shunga o'xshash
webview.settings.run {
    javaScriptEnabled = true
    databaseEnabled = true
}

Biroq, ularning bir-biridan farq qiladigan xususiyati oddiy funktsiya, ya'ni ikkinchisi kengaytma funktsiyasi, ya'ni T.run.

Shunday qilib, har birining afzalligi nimada?

Tasavvur qiling, agar webview.settings null bo'lishi mumkin bo'lsa, ular quyidagicha ko'rinadi.

// Yaq!
bilan (webview.settings) {
      bu? .javaScriptEnabled = true
      bu? .databaseEnabled = true
}
// Yaxshi.
webview.settings? .run {
    javaScriptEnabled = true
    databaseEnabled = true
}

Bunday holda, T.run kengaytma funktsiyasi yaxshiroq, chunki uni ishlatishdan oldin null mavjudligini tekshirish uchun murojaat qilishimiz mumkin.

2. Bu va boshqalar

Agar biz T.run va T.letga qarasak, ikkala funktsiya bir-biridan farq qiladi, argumentni qabul qilish usuli. Quyida ikkala funktsiya uchun bir xil mantiq ko'rsatilgan.

stringVariable? .run {
      println ("Ushbu qatorning uzunligi $ uzunligi")
}
// Xuddi shunday.
stringVariable? .let {
      println ("Ushbu satr uzunligi $ {it.length}")
}

Agar siz T.run funktsiyasining imzosini tekshirsangiz, T.run kengaytma funktsiyasini chaqirish bloki sifatida qilinganligini ko'rasiz: T. (). Demak, T doirasida hamma narsa bu deb nomlanishi mumkin. Dasturlashda bu ko'p hollarda o'tkazib yuborilishi mumkin. Shuning uchun yuqoridagi misolimizda biz $ {this.length} o'rniga println bayonotida $ uzunligidan foydalanishimiz mumkin. Men buni buni dalil sifatida yuborish deb atayman.

Ammo T.let funktsiyasi imzosi uchun T.let o'zini blokka: (T) funktsiyaga yuborayotganini sezasiz. Demak, bu lambda dalili uni yuborganga o'xshaydi. U o'z vazifasi doirasiga kirishi mumkin. Shuning uchun men buni dalil sifatida yuborish deb atayman.

Yuqoridagilardan ko'rinib turibdiki, T.run T.letdan ustunroq bo'lib tuyuladi, chunki u aniq emas, ammo T.let funktsiyasining quyidagi bir qancha nozik tomonlari bor: -

  • T.let berilgan o'zgaruvchili funktsiya / a'zolardan va tashqi sinf funktsiyasi / a'zolardan foydalanishni aniq farqlashni ta'minlaydi
  • Agar buni o'tkazib yubormasangiz, masalan. agar u funktsiya parametrlari sifatida yuborilsa, yozishga qaraganda qisqaroq va aniqroq bo'ladi.
  • T.let o'zgartirilgan o'zgaruvchiga yaxshiroq nom berishga imkon beradi, ya'ni uni boshqa biron bir nomga aylantira olasiz.
stringVariable? .let {
      nonNullString ->
      println ("Nol bo'lmagan satr - bu $ nonNullString")
}

3. Boshqa va boshqa turlarini qaytaring

Endi, agar T.ning ichki funktsiyasi doirasiga nazar tashlasak, T.let va T.also ikkalasi bir-biriga o'xshashdir.

stringVariable? .let {
      println ("Ushbu satr uzunligi $ {it.length}")
}
// Xuddi shu kabi
stringVariable? .also {
      println ("Ushbu satr uzunligi $ {it.length}")
}

Biroq, ularning qaytib kelgan narsalari juda boshqacha. T.let qiymatning boshqa turini qaytaradi, T.also esa T ning qiymatini qaytaradi, ya'ni.

Ikkalasi ham zanjirlash funktsiyasi uchun foydalidir, bu erda byT.let sizga operatsiyani rivojlantirishga imkon beradi va T.also sizga bir xil o'zgaruvchini bajarishga imkon beradi, ya'ni.

Quyidagi kabi oddiy rasm

val original = "abc"
// Qiymatni o'zgartiring va keyingi zanjirga yuboring
original.let {
    println ("Asl satr bu - bu") // "abc"
    it.reversed () // uni keyingi quruvchiga yuborish uchun parametr sifatida rivojlantiradi
} .let {
    println ("Teskari satr bu - bu") // "cba"
    it.length // boshqa turga o'zgarishi mumkin
} .let {
    println ("Satrning uzunligi - bu $") // 3
}
// Noto'g'ri
// Xuddi shu qiymat zanjirda yuborilgan (javob noto'g'ri)
original.also {
    println ("Asl satr bu - bu") // "abc"
    it.reversed () // uni rivojlantirsak ham, foydasiz
}.shuningdek {
    println ("Teskari satr bu $ {it}") // "abc"
    it.length // uni rivojlantirsak ham, foydasiz
}.shuningdek {
    println ("Satrning uzunligi $ {bu}") // "abc"
}
// shuningdek tuzatildi (ya'ni original satr sifatida manipulyatsiya qilish)
// Xuddi shu qiymat zanjirda yuboriladi
original.also {
    println ("Asl satr bu - bu") // "abc"
}.shuningdek {
    println ("Teskari satr - $ {it.reversed ()}") // "cba"
}.shuningdek {
    println ("Satrning uzunligi $ {it.length}") // 3
}

T.also yuqorida ma'nosiz bo'lib tuyulishi mumkin, chunki ularni osonlikcha bitta funktsional blokga birlashtirishimiz mumkin. Ehtiyotkorlik bilan o'ylab ko'rsangiz, uning yaxshi afzalliklari bor

  1. U bir xil ob'ektlarda aniq ajratish jarayonini ta'minlaydi, ya'ni kichik funktsional qismni yaratadi.
  2. Ishlatishdan oldin o'z-o'zini manipulyatsiya qilish juda zo'r bo'lishi mumkin va bu zanjirli quruvchi ishini bajaradi.

Ikkalasi ham zanjirni birlashtirganda, ya'ni biri o'zini rivojlantiradi, boshqasi o'zini saqlab qoladi, masalan kuchli narsaga aylanadi quyida

// Oddiy yondashuv
fun makeDir (yo'l: satr): Fayl {
    val natijasi = Fayl (yo'l)
    result.mkdirs ()
    qaytish natijasi
}
// Yaxshilangan yondashuv
qiziqarli makeDir (yo'l: satr) = path.let {Fayl (u)} .also {it.mkdirs ()}

Barcha atributlarga qarash

3 ta atributni ko'rib chiqib, funktsiya xatti-harakatlari haqida ko'p narsa bilishimiz mumkin. Yuqorida aytib o'tilmaganidek, T.apply funktsiyasini tasvirlab beray. T.applining uchta atributlari quyida keltirilgan.

  1. Bu kengaytma funktsiyasidir
  2. Buni dalil sifatida yuboradi.
  3. Buni qaytaradi (ya'ni o'zi)

Shunday qilib, undan foydalanib, tasavvur qilish mumkin, uni qanday ishlatsa bo'ladi

// Oddiy yondashuv
qiziqarli createInstance (args: to'plam): MyFragment {
    val fragment = MyFragment ()
    fragment.arguments = args
    qaytish qismi
}
// Yaxshilangan yondashuv
qiziqarli createInstance (args: to'plam)
              = MyFragment (). Apply {argument = args}

Yoki biz ob'ektlar yaratilmagan zanjirli zanjir yaratishga imkon yaratamiz.

// Oddiy yondashuv
fun createIntent (intentData: String, intentAction: String): Niyat {
    val intent = niyat ()
    intent.action = intentAction
    intent.data = Uri.parse (intentData)
    qaytish niyati
}
// Yaxshilangan yondashuv, zanjir
qiziqarli createIntent (intentData: String, intentAction: String) =
        Niyat (). Apply {action = intentAction}
                .apply {data = Uri.parse (intentData)}

Funktsiyalarni tanlash

Shunday qilib, 3 ta atribut bilan biz endi funktsiyalarni shunga ko'ra tasniflashimiz mumkin. Va shunga asoslanib, biz quyida qaror daraxti hosil qilishimiz mumkin, bu biz kerak bo'lgan narsaga qarab qanday funktsiyadan foydalanishni tanlashimizga yordam beradi.

Umid qilamanki, yuqorida keltirilgan qaror daraxti funktsiyalarni yanada aniqroq tushuntiradi va qarorlarni qabul qilishni soddalashtiradi, bu funktsiyalardan to'g'ri foydalanishga imkon beradi.

Ushbu blogga javob sifatida ushbu funktsiyalardan qanday foydalanganingiz haqida yaxshi misollar keltirsangiz bo'ladi. Sizdan eshitishni istardim. Bu boshqalarga foyda keltirishi mumkin.

Ushbu xabarni qadrlaysiz va sizga foydali deb umid qilaman. Boshqalar bilan baham ko'ring.

Siz mening boshqa qiziqarli mavzularimni bu erda ko'rishingiz mumkin.

Kichik maslahatlar va Android, Kotlin va boshqa mavzularda o'rganish uchun meni o'rta, Twitter yoki Facebook-da kuzatib boring. ~ Elye ~