kengaytma funksiyasi — Kotlin mexanizmi bo'lib, mavjud sinflarga meros olmasdan va manba kodini o'zgartirmasdan yangi metodlar qo'shish imkonini beradi. Funksiya qabul qiluvchi tip prefiksi bilan e'lon qilinadi va shu tipning oddiy metodi sifatida chaqiriladi. Kotlin Documentation, 2025 ga ko'ra, kengaytma funksiyalari birinchi parametr-qabul qiluvchi bilan statik metodlarga kompilyatsiya qilinadi va bu oddiy chaqiruvlar bilan solishtirganda nol overhead ni kafolatlaydi.
Asosiy fikrlar
Kengaytma funksiyasi sinfdan tashqarida e'lon qilingan, ammo uning metodi sifatida chaqiriladigan funksiyadir. U yangi metod qo'shiladigan qabul qiluvchi tipni qabul qiladi. Funksiya ichida this kalit so'zi qabul qiluvchi tipning namunasiga ishora qiladi. Bu yondashuv final sinflarni, uchinchi tomon kutubxonalari sinflarini va hatto primitiv tiplarni o'ramlar yaratmasdan kengaytirish imkonini beradi.
Java-dan farqli o'laroq, mavjud sinfga metod qo'shish uchun meros yoki statik yordamchi sinf talab qilinadi, Kotlin boilerplate-siz nafis yechim taklif qiladi. Ma'lumotlarga ko'ra Kotlin Foundation (2024) tadqiqotida, kengaytma funksiyalari tilning eng ko'p ishlatiladigan beshta xususiyati qatoriga kiradi — kunlik ishda Kotlin dasturchilarining 78% i ulardan foydalanadi.
Kotlin kompilyatori kengaytma funksiyasini statik metodga aylantiradi, bunda birinchi argument sifatida qabul qiluvchi namunasi uzatiladi. Bu kengaytma funksiyalari maqsadli sinfning bayt-kodini o'zgartirmasligi va inkapsulyatsiyani buzmasligini anglatadi — qabul qiluvchining faqat ochiq maydonlari va metodlari mavjud.
Kengaytma funksiyalaridan mantiqiy jihatdan ma'lum bir tipga bog'liq bo'lgan, ammo uning manba kodiga qo'shib bo'lmaydigan toza yordamchi funksiyalarni yozish uchun foydalaning.
Kengaytma funksiyasining asosiy sintaksisi: qabul qiluvchi tip nomi, nuqta, funksiya nomi, keyin parametrlar va qaytariladigan tip. Funksiya ichida qabul qiluvchi this orqali mavjud.
// String uchun kengaytma funksiyasi
fun String.isEmail(): Boolean {
return this.contains("@") && this.contains(".")
}
// Oddiy String metodi sifatida chaqiriladi
val result = "user@example.com".isEmail() // true
Ushbu misolda isEmail() barcha satrlar uchun mavjud bo'ladi. Funksiya ichida this metod chaqiriladigan satrning o'zidir. Kotlin ko'p hollarda this-ni tashlab qo'yishga imkon beradi — this.contains("@") o'rniga oddiygina contains("@") yozish mumkin.
Kengaytma funksiyalari qo'shimcha parametrlarni qabul qilishi va istalgan turdagi qiymatni qaytarishi mumkin. Bu ularni oddiy sintaktik shakar emas, balki to'liq huquqli funksiyalarga aylantiradi.
fun List<Int>.defaultIfEmpty(default: Int): List<Int> {
if (this.isEmpty()) return listOf(default)
return this
}
val populated = listOf(1, 2).defaultIfEmpty(0)
val empty = listOf<Int>().defaultIfEmpty(0)
default parametri bo'sh ro'yxat uchun qaytariladigan qiymatni belgilaydi. Kengaytma funksiyasi generic bo'lishi mumkin — List
Kotlin-dagi kengaytma funksiyalari statik dispetcherlashtirishdan foydalanadi, virtual emas. Bu oddiy sinf metodlaridan asosiy farqdir. Qaysi kengaytma funksiyasi chaqirilishi kompilyatsiya bosqichida o'zgaruvchining statik tipiga qarab belgilanadi, uning ish vaqtidagi haqiqiy tipiga qarab emas.
open class Animal
class Dog : Animal()
fun Animal.speak() = "Hayvon ovozi"
fun Dog.speak() = "Vovullash"
fun test() {
val animal: Animal = Dog()
println(animal.speak()) // "Hayvon ovozi" — statik tip Animal
val dog: Dog = Dog()
println(dog.speak()) // "Vovullash" — statik tip Dog
}
O'zgaruvchi animal Dog namunasiga ishora qilsa-da, Animal uchun kengaytma funksiyasi chaqiriladi, chunki o'zgaruvchining statik tipi Animal. Agar speak() sinfning virtual metodi bo'lganda, Dog.speak() chaqirilgan bo'lardi. Bu xususiyat kengaytma funksiyalari asosidagi API-larni loyihalashda hisobga olinishi muhim.
Kengaytma funksiyalari sinf a'zosi emas — ular oddiy funksiyalar bo'lib, boshqa faylda ishlatish uchun import talab qiladi. Kotlin ikki import variantini taklif qiladi: funksiya nomi bilan yoki nomini o'zgartirish bilan.
// Nom bo'yicha import
import com.example.extensions.isEmail
// Alias bilan import (konfliktlarni hal qilish uchun)
import com.example.extensions.isEmail as isValidEmail
// Importdan keyin chaqirish
val valid = "test@test.com".isEmail()
Nomini o'zgartirish as orqali nom konfliktlarida foydalidir — masalan, ikki kutubxona bir xil tip uchun bir xil nomli kengaytma funksiyasini taqdim etsa. Bu holda ulardan birini boshqa nom bilan import qilib, yangi nom orqali chaqirish mumkin.
Kengaytma funksiyalari turli darajalarda e'lon qilinishi mumkin:
| Daraja | Ko'rinish | Misol |
|---|---|---|
| Top-level | Importdan keyin butun loyiha | fun String.isEmail() |
| Member extension | Ega sinf ichida | class A { fun B.ext() } |
| Local | Funksiya ichida | fun test() { fun String.ext() } |
Member extension functions — kengaytma funksiyasi boshqa sinf ichida e'lon qilingan maxsus holat. Bu holda kengaytma funksiyasi ichida ham qabul qiluvchi (funksiyaning this-i), ham tashqi sinf a'zolari mavjud.
Agar sinf kengaytma funksiyasi bilan bir xil imzoga ega metodga ega bo'lsa, har doim sinf a'zosi chaqiriladi. Kengaytma funksiyasi hech qachon sinf metodini bekor qilmaydi — bu tasodifiy bekor qilishlarning oldini olish uchun arxitektura qaroridir.
class User {
fun greet() = "Salom sinfdan"
}
fun User.greet() = "Hello from extension"
fun main() {
val user = User()
println(user.greet()) // "Salom sinfdan"
}
Kengaytma funksiyasi keyinroq aniqlansa va bir xil imzoga ega bo'lsa ham, kompilyator sinf metodini tanlaydi. Kotlin kompilyatori bunday holatni aniqlaganda ogohlantirish chiqaradi. Sinf metodi mavjud bo'lganda kengaytma funksiyasini chaqirishning yagona yo'li — unga oddiy funksiya sifatida murojaat qilish: greet(user).
Android dasturlashida kengaytma funksiyalari View, Context va fragmentlar bilan ishlash uchun standart vositaga aylangan. Android KTX kutubxonasi kengaytma funksiyalari asosida qurilgan bo'lib, Android API uchun qulay o'ramlarni taqdim etadi.
// View bilan ishlash uchun kengaytma funksiyasi
fun View.show() {
visibility = View.VISIBLE
}
fun View.hide() {
visibility = View.GONE
}
// Context uchun kengaytma funksiyasi — toast
fun Context.toast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
// DSL quruvchi sifatida kengaytma funksiyasi
fun String.colorFormat(color: String): String =
"$color$this\u001b[0m"
toast() kengaytma funksiyasi Context-ga bog'liq chaqiruvlarni ixcham qiladi: Toast.makeText(context, message, length).show() yozish o'rniga context.toast("Matn") yozish kifoya. Bu boilerplate-ni kamaytiradi va kodni o'qishni osonlashtiradi.
Tez-tez beriladigan savollar
Yo'q, kengaytma funksiyalari statik dispetcherlashtirishdan foydalanadi. Agar asosiy sinf va kichik sinf uchun bir xil kengaytma funksiyasi e'lon qilinsa, qaysi biri chaqirilishi kompilyatsiya bosqichida o'zgaruvchining statik tipi bilan belgilanadi, ish vaqtidagi haqiqiy tip bilan emas.
Nullable qabul qiluvchi tiplar uchun kengaytma funksiyalari e'lon qilinishi mumkin: fun String?.isNullOrEmail(). Bunday funksiya ichida this null bo'lishi mumkin, shuning uchun xavfsiz chaqiruv operatorlaridan yoki aniq null tekshiruvidan foydalanish kerak.
Yo'q, kengaytma funksiyalari statik metodlarga kompilyatsiya qilinadi. Bayt-kod darajasida kengaytma funksiyasining chaqiruvi birinchi parametr-qabul qiluvchi bilan statik metod chaqiruviga o'xshash. Hech qanday refleksiya yoki dinamik dispetcherlashtirish mavjud emas.
Ha, kengaytma xususiyatlari kengaytma funksiyalariga o'xshash ishlaydi, lekin holat saqlay olmaydi — faqat getter va setter. Masalan: val List<Int>.sum get() = reduce(Int::plus). Ular ham getter/setter statik metodlariga kompilyatsiya qilinadi.
Java-da StringUtils.isEmail(str) yozasiz, Kotlin-da esa — str.isEmail(). Farq faqat sintaksisda emas: kengaytma funksiyalari IDE-da avtomatik to'ldirishni qo'llab-quvvatlaydi, chaqiruv zanjirlarining o'qilishini yaxshilaydi va IDE-ga aniq tip uchun tegishli funksiyalarni taklif qilish imkonini beradi. Java-da bunday imkoniyatlar mavjud emas.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.