Destructuring declaration — bu Kotlin-ning bir ifodada obyektni bir nechta o'zgaruvchiga ajratish imkoniyati. val (name, age) = user konstruksiyasi bir vaqtning o'zida ikkita o'zgaruvchini e'lon qiladi, ularga obyekt komponentlaridan qiymatlar beradi. Kotlin hujjatlariga (2026) ko'ra, destrukturizatsiya data class bilan ishlashda kod hajmini 30–50% ga kamaytiradi. Destructuring declaration kodni ixchamroq va o'qilishi osonroq qiladi.
Asosiy
Destructuring declaration (ajratuvchi deklaratsiya) — bu Kotlin-ning sinf namunasini bir ifodada bir nechta o'zgaruvchiga ajratishga imkon beruvchi sintaktik konstruksiyadir. Chap tomonda qavslardagi o'zgaruvchilar ro'yxati, o'ng tomonda ajratiladigan obyekt joylashgan. Kotlin har bir o'zgaruvchi uchun mos keladigan componentN() funksiyasini avtomatik chaqiradi, bu yerda N qavsdagi o'zgaruvchining tartib raqamidir.
Destructuring declaration eng ko'p data class bilan ishlatiladi. Kotlin kompilyatori data class uchun avtomatik ravishda component1(), component2() va h.k. funksiyalarni yaratadi — birlamchi konstruktordagi xususiyatlar soniga ko'ra. Data modifikatorisiz oddiy sinflar uchun componentN() yaratilmaydi, lekin ularni operator kalit so'zi bilan qo'lda belgilash mumkin.
Destructuring declaration juftliklar kolleksiyalari, funksiya natijalari va Map-ni aylanish bilan ishlashda kodni soddalashtirish qobiliyati tufayli mashhur namunaga aylandi. person.firstName, person.lastName yozish o'rniga dasturchi val (firstName, lastName) = person yozadi. Bu qatorlar sonini kamaytiradi va o'qishni osonlashtiradi, ayniqsa sikllarda va lambdalarda.
val (a, b) = obj konstruksiyasiga duch kelganda, Kotlin kompilyatori quyidagi kodni yaratadi: val a = obj.component1(); val b = obj.component2(). Agar o'zgaruvchilar var bilan e'lon qilingan bo'lsa, var tayinlari yaratiladi. Har bir o'zgaruvchining turi tegishli componentN() funksiyasining qaytarish turidan olinadi. Bu shuni anglatadiki, destructuring declaration to'liq tip-xavfsizdir va kompilyatsiya bosqichida tekshiriladi.
data class Person(val firstName: String, val lastName: String, val age: Int)
fun main() {
val person = Person("Alice", "Smith", 30)
// Destrukturizatsiya: component1(), component2(), component3()
val (firstName, lastName, age) = person
println("$firstName $lastName, $age yosh")
}
Listingda Person — uch xususiyatli data class. Kotlin component1() → firstName, component2() → lastName, component3() → age yaratadi. val (firstName, lastName, age) = person ifodasi bu funksiyalarni chaqiradi va natijalarni tayinlaydi. Muhim: o'zgaruvchi nomlari xususiyat nomlari bilan mos kelmasligi mumkin — kompilyator faqat componentN() tartibiga va ularning turlariga qaraydi. Qolganlarini hisobga olmagan holda faqat birinchi N xususiyatni ajratish mumkin.
Data class — destructuring declaration uchun asosiy nomzod. Har bir data class birlamchi konstruktorning barcha xususiyatlari uchun avtomatik ravishda componentN() oladi. componentN() tartibi xususiyatlarning e'lon qilish tartibiga mos keladi. Bu shuni anglatadiki, data class-da maydonlar tartibi o'zgartirilganda destrukturizatsiyada o'zgaruvchilar tartibi o'zgaradi — bu esa sezilmaydigan xatolarga olib kelishi mumkin.
// Pair destrukturizatsiyasi
val pair = Pair("key", 42)
val (key, value) = pair
println("$key -> $value")
// Triple destrukturizatsiyasi
val triple = Triple("A", "B", "C")
val (first, second, third) = triple
// Siklda Map.Entry
val map = mapOf("a" to 1, "b" to 2)
for ((k, v) in map) {
println("$k = $v")
}
Pair va Triple — ikki va uch komponent uchun tayyor destrukturizatsiya bilan standart sinflar. Pair ko'pincha alohida data class yaratmasdan ikkita bog'liq qiymatni qaytarishi kerak bo'lgan funksiyalarning qaytarish turi sifatida ishlatiladi. Map.Entry ustida for siklida (k, v) = entry konstruksiyasi component1() va component2() orqali kalit va qiymatni destrukturizatsiya qiladi. Bu Kotlin-da Map-ni aylanish uchun standart namuna bo'lib, key va value ning ochiq chaqiruvlarini butunlay almashtiradi.
Agar destrukturizatsiya paytida ba'zi komponentlar kerak bo'lmasa, Kotlin ularni pastki chiziq _ bilan almashtirishga imkon beradi. Bu o'qilishni yaxshilaydi — o'quvchi darhol komponent e'tiborga olinmaganligini ko'radi. Bundan tashqari, _ dan foydalanish tasodifan ishga tushirilmagan o'zgaruvchiga murojaat qilishning oldini oladi: kompilyator _ uchun hech qanday o'zgaruvchi yaratmaydi, bu esa foydalanilmayotgan o'zgaruvchilar haqidagi ogohlantirishlarni yo'q qiladi.
data class Order(
val id: Long,
val customerName: String,
val amount: Double,
val status: String
)
fun process(orders: List<Order>) {
for ((id, _, amount) in orders) {
println("Buyurtma $id: $amount")
}
}
Listingda Order to'rt xususiyatga ega, ammo siklida faqat id va amount kerak. customerName o'rnidagi pastki chiziq kompilyatorga «component2()-ni tashlab ket» deydi. Kotlin component2() ni chaqirmaydi va bu komponent uchun o'zgaruvchi yaratmaydi. Muhim: pastki chiziq faqat destructuring declaration-da ishlatilishi mumkin, lekin data class konstruktorida emas. Agar ketma-ket bir nechta komponent tashlab ketilsa, har biriga o'z pastki chizig'i to'g'ri keladi.
Data modifikatorisiz sinflar uchun operator kalit so'zini qo'shish orqali componentN() qo'lda belgilash mumkin. Bu istalgan sinf bilan, jumladan manba kodi o'zgartirilmaydigan uchinchi tomon sinflari bilan destructuring declaration ishlatishga imkon beradi — operator bilan kengaytma funksiyasini yozish kifoya. Bu yondashuv kutubxona sinflari va avtomatik componentN() ga ega bo'lmagan Java koddan sinflar uchun ayniqsa foydalidir.
class Rect(val width: Int, val height: Int)
operator fun Rect.component1(): Int = width
operator fun Rect.component2(): Int = height
// Getterlari bo'lgan Java sinfi uchun
operator fun Dimension.component1(): Int = width
operator fun Dimension.component2(): Int = height
fun main() {
val rect = Rect(1920, 1080)
val (w, h) = rect
println("Rezolyutsiya: ${w}x${h}")
}
Misolda Rect — datasiz oddiy sinf. operator fun component1() = width va component2() = height bilan kengaytma funksiyalari destrukturizatsiya qo'llab-quvvatlashini qo'shadi. Xuddi shunday java.awt.Dimension uchun: Dimension-da operator kengaytmasi uni width va height ga ajratishga imkon beradi. Cheklov: destructuring declaration uchun maksimal komponentlar soni — 5. Nazariy jihatdan component6() va undan yuqorilarni belgilash mumkin, ammo Kotlin qavslarda 6+ o'zgaruvchi uchun mos sintaksis yaratmaydi.
Tez-tez beriladigan savollar
Ha, har bir data class birlamchi konstruktorning barcha xususiyatlari uchun avtomatik ravishda componentN() oladi. Sinf tanasida e'lon qilingan xususiyatlar (val/var holda konstruktor orqali) componentN() yaratmaydi.
Agar val (a, b, c) = obj da obyekt faqat ikkita component funksiyasiga ega bo'lsa, kompilyator xato beradi. Agar o'zgaruvchilar kam bo'lsa (val (a) = pair), Kotlin faqat component1() ni chaqiradi va component2() ni e'tiborga olmaydi — xato bo'lmaydi.
Ha, Map.Entry destrukturizatsiyani qo'llab-quvvatlaydi: val (key, value) = map.entries.first(). Butun Map-ni birdaniga destrukturizatsiya qilish ishlamaydi — faqat elementma-element, for siklida yoki iterator orqali.
Ha, Kotlin lambda parametrlarida destrukturizatsiyani qo'llab-quvvatlaydi: map.forEach { (k, v) -> ... }. Lambda parametrlarida data class uchun parametr atrofida ichma-ich qavslar qo'shish kerak.
Kotlin destructuring declaration da 5 ta o'zgaruvchigacha qo'llab-quvvatlaydi. Agar beshdan ortiq xususiyatni ajratish kerak bo'lsa, ularni ichma-ich data class larda birlashtiring yoki bir o'zgaruvchi ichida Pair/Triple dan foydalaning.
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.