A Destructuring declaration — a Kotlin azon képessége, hogy egy objektumot több változóra bontson egyetlen kifejezésben. A val (name, age) = user konstrukció egyszerre két változót deklarál, hozzárendelve az objektum komponenseiből származó értékeket. A Kotlin dokumentáció (2026) szerint a destrukturálás 30–50%-kal csökkenti a kód mennyiségét data class használatakor. Destructuring declaration tömörebbé és olvashatóbbá teszi a kódot.
Főbb pontok
Destructuring declaration (destrukturáló deklaráció) — egy szintaktikai konstrukció Kotlinban, amely lehetővé teszi egy osztály példányának több változóra bontását egyetlen kifejezésben. A bal oldal a változók listáját tartalmazza zárójelekben, a jobb oldal — a bontandó objektumot. Kotlin automatikusan meghívja minden változóhoz a megfelelő componentN() függvényt, ahol N a változó sorszáma a zárójelekben.
A destructuring declaration leggyakrabban data class-szal használatos. A Kotlin fordító automatikusan generalja data class-hoz a component1(), component2() és így tovább függvényeket — az elsődleges konstruktor tulajdonságainak száma szerint. A data modifikátor nélküli szokásos osztályokhoz componentN() nem generálódik, de kézzel definiálhatók operator függvényként az operator kulcsszóval.
A destructuring declaration népszerű mintává vált a kód egyszerűsítésére való képessége miatt párok gyűjteményeivel, függvényeredményekkel és Map bejárásával való munka során. A person.firstName, person.lastName írása helyett a fejlesztő val (firstName, lastName) = person-t ír. Ez csökkenti a sorok számát és növeli az olvashatóságot, különösen ciklusokban és lambdákban.
A val (a, b) = obj konstrukcióval találkozva a Kotlin fordító a következő kódot generalja: val a = obj.component1(); val b = obj.component2(). Ha a változók var-ral vannak deklarálva, var hozzárendelések generalódnak. Minden változó típusa a megfelelő componentN() függvény visszatérési típusából származik. Ez azt jelenti, hogy a destructuring declaration teljesen típusbiztos és fordítási fázisban ellenőrződik.
data class Person(val firstName: String, val lastName: String, val age: Int)
fun main() {
val person = Person("Alice", "Smith", 30)
// Destrukturálás: component1(), component2(), component3()
val (firstName, lastName, age) = person
println("$firstName $lastName, $age éves")
}
A listában Person — data class három tulajdonsággal. Kotlin generalja: component1() → firstName, component2() → lastName, component3() → age. A val (firstName, lastName, age) = person kifejezés meghívja ezeket a függvényeket és hozzárendeli az eredményeket. Fontos: a változónevek nem feltétlenül egyeznek a tulajdonságnevekkel — a fordító csak a componentN() sorrendjét és típusait nézi. Csak az első N tulajdonság bontható ki, a többi figyelmen kívül hagyható.
Data class — a fő jelölt a destructuring declaration számára. Minden data class automatikusan megkapja a componentN()-t az elsődleges konstruktor összes tulajdonságához. A componentN() sorrendje megfelel a tulajdonságok deklarálási sorrendjének. Ez azt jelenti, hogy a mezők sorrendjének megváltoztatásakor a data class-ban megváltozik a változók sorrendje a destrukturálásban — ami észrevétlen hibákhoz vezethet.
// Pair destrukturálás
val pair = Pair("key", 42)
val (key, value) = pair
println("$key -> $value")
// Triple destrukturálás
val triple = Triple("A", "B", "C")
val (first, second, third) = triple
// Map.Entry ciklusban
val map = mapOf("a" to 1, "b" to 2)
for ((k, v) in map) {
println("$k = $v")
}
Pair és Triple — szabvány osztályok kész destrukturálással két és három komponensre. A Pair gyakran használatos olyan függvények visszatérési típusaként, amelyeknek két összefüggő értéket kell visszaadniuk külön data class létrehozása nélkül. A Map.Entry feletti for ciklusban a (k, v) = entry konstrukció a kulcsot és értéket a component1() és component2() segítségével destrukturálja. Ez a Map bejárásának szabványos mintája Kotlinban, teljesen helyettesítve a key és value explicit hívásait.
Ha a destrukturálásnál néhány komponensre nincs szükség, Kotlin lehetővé teszi ezek aláhúzással _ történő helyettesítését. Ez javítja az olvashatóságot — az olvasó azonnal látja, hogy a komponens figyelmen kívül van hagyva. Ezenkívül a _ használata megakadályozza a véletlen hozzáférést egy inicializálatlan változóhoz: a fordító nem hoz létre semmilyen változót a _ számára, ami megszünteti a nem használt változókra vonatkozó figyelmeztetéseket.
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("Rendelés $id: $amount")
}
}
A listában Order négy tulajdonsággal rendelkezik, de a ciklusban csak id és amount szükséges. Az aláhúzás a customerName helyén azt mondja a fordítónak: „hagyd ki a component2()-t”. Kotlin nem hívja meg a component2()-t és nem hoz létre változót ehhez a komponenshez. Fontos: aláhúzás csak destructuring declaration-ban használható, de nem a data class konstruktorában. Ha több komponens kerül kihagyásra egymás után, mindegyiknek saját aláhúzása van.
A data modifikátor nélküli osztályokhoz kézzel definiálható a componentN() a operator kulcsszó hozzáadásával. Ez lehetővé teszi a destructuring declaration használatát bármely osztállyal, beleértve a külső osztályokat is, amelyek forráskódja nem módosítható — elég egy kiterjesztési függvényt írni operator-ral. Ez a megközelítés különösen hasznos könyvtári osztályok és Java kódból származó osztályok számára, amelyeknek nincs automatikus componentN()-jük.
class Rect(val width: Int, val height: Int)
operator fun Rect.component1(): Int = width
operator fun Rect.component2(): Int = height
// Getterekkel rendelkező Java osztályhoz
operator fun Dimension.component1(): Int = width
operator fun Dimension.component2(): Int = height
fun main() {
val rect = Rect(1920, 1080)
val (w, h) = rect
println("Felbontás: ${w}x${h}")
}
A példában Rect — szokásos osztály data nélkül. Az operator fun component1() = width és component2() = height kiterjesztési függvények hozzáadják a destrukturálás támogatását. Hasonlóan a java.awt.Dimension számára: az operator kiterjesztés a Dimension-on lehetővé teszi annak width és height összetevőkre bontását. Korlátozás: a maximális komponensek száma destructuring declaration esetében — 5. Elvileg definiálható component6() és magasabb is, de Kotlin nem fog megfelelő szintaxist generalni 6+ változóhoz zárójelekben.
Gyakran ismételt kérdések
Igen, minden data class automatikusan megkapja a componentN()-t az elsődleges konstruktor összes tulajdonságához. Az osztály törzsében deklarált tulajdonságok (val/var nélküli konstruktoron keresztül) nem generalnak componentN()-t.
Ha a val (a, b, c) = obj-ben az objektumnak csak két component függvénye van, a fordító hibát jelez. Ha kevesebb a változó (val (a) = pair), Kotlin csak a component1()-t hívja meg és figyelmen kívül hagyja a component2()-t — hiba nem történik.
Igen, a Map.Entry támogatja a destrukturálást: val (key, value) = map.entries.first(). Az egész Map-re egyszerre a destrukturálás nem működik — csak elemenként, for ciklusban vagy iterátoron keresztül.
Igen, a Kotlin támogatja a destrukturálást lambda paraméterekben: map.forEach { (k, v) -> ... }. A data class lambdákban történő használatához egymásba ágyazott zárójeleket kell hozzáadni a paraméter köré.
A Kotlin legfeljebb 5 változót támogat a destructuring declaration-ban. Ha több mint öt tulajdonságot kell kibontani, egyesítse őket egymásba ágyazott data class-okban, vagy használjon Pair/Triple-t egy változón belül.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is