Destructuring declaration — је могућност Kotlin-а да разложи објекат на неколико промењливих у једном изразу. Конструкција val (name, age) = user истовремено декларише двије промењливе, додељујући им вриједности из компонената објекта. Према документацији Kotlin-а (2026), деструктуризација смањује обим кода при раду са data class за 30–50%. Destructuring declaration чини код језгровитијим и читљивијим.
Главне тачке
Destructuring declaration (деструктурирајућа декларација) — је синтаксичка конструкција Kotlin-а која омогућава разлагање инстанце класе на неколико промењливих у једном изразу. Лијева страна садржи листу промењљивих у заградама, десна — објекат који се разлаже. Kotlin аутоматски позива за сваку промењливу одговарајућу функцију componentN(), гдје је N редни број промењљиве у заградама.
Destructuring declaration се најчешће користи са data class. Компилатор Kotlin-а аутоматски генерише за data class функције component1(), component2() и тако даље — према броју својстава у примарном конструктору. За обичне класе без модификатора data, componentN() се не генеришу, али се могу ручно дефинисати као операторске функције са кључном речју operator.
Destructuring declaration је постала популаран образац захваљујући својој способности да поједностављује код при раду са колекцијама парова, резултатима функција и прегледањем Map. Уместо писања person.firstName, person.lastName, програмер пише val (firstName, lastName) = person. Ово смањује број редова и повећава читљивост, посебно у петљама и ламбдама.
При сусрету са конструкцијом val (a, b) = obj, компилатор Kotlin-а генерише код: val a = obj.component1(); val b = obj.component2(). Ако су промењљиве декларисане са var, генеришу се var доделе. Тип сваке промењливе се изводи из повратног типа одговарајуће функције componentN(). То значи да је destructuring declaration потпуно типно безбједна и провјерава се у фази компилације.
data class Person(val firstName: String, val lastName: String, val age: Int)
fun main() {
val person = Person("Alice", "Smith", 30)
// Destrukturing: component1(), component2(), component3()
val (firstName, lastName, age) = person
println("$firstName $lastName, $age godina")
}
У листингу Person — data class са три својства. Kotlin генерише component1() → firstName, component2() → lastName, component3() → age. Израз val (firstName, lastName, age) = person позива ове функције и додељује резултате. Важно: имена промењљивих могу се разликовати од имена својстава — компилатор гледа само редослед componentN() и њихове типове. Може се разложити само првих N својстава, игноришући остала.
Data class — главни кандидат за destructuring declaration. Свака data class аутоматски добија componentN() за сва својства примарног конструктора. Редослед componentN() одговара редоследу декларације својстава. То значи да при промјени редоследа поља у data class, мења се редослед промењљивих у деструктуризацији — што може довести до неприметних грешака.
// Destrukturing Pair
val pair = Pair("key", 42)
val (key, value) = pair
println("$key -> $value")
// Destrukturing Triple
val triple = Triple("A", "B", "C")
val (first, second, third) = triple
// Map.Entry u petlji
val map = mapOf("a" to 1, "b" to 2)
for ((k, v) in map) {
println("$k = $v")
}
Pair и Triple — стандардне класе са готовом деструктуризацијом на двије и три компоненте. Pair се често користи као повратни тип функција које треба да врате двије повезане вриједности без креирања засебне data class. У for петљи преко Map.Entry, конструкција (k, v) = entry деструктурише кључ и вриједност кроз component1() и component2(). Ово је стандардни образац за прегледање Map-а у Kotlin-у, који потпуно замењује експлицитне позиве key и value.
Ако при деструктуризацији неке компоненте нису потребне, Kotlin дозвољава да се замијене подвлаком _. Ово побољшава читљивост — читалац одмах види да је компонента игнорисана. Поред тога, употреба _ спречава случајни приступ неиницијализованој промењљивој: компилатор не ствара никакву промењљиву за _, чиме се елиминишу упозорења о некоришћеним промењљивима.
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("Narudžbina $id: $amount")
}
}
У листингу Order има четири својства, али су у петљи потребни само id и amount. Подвлака на месту customerName говори компилатору „прескочи component2()“. Kotlin не позива component2() и не ствара промењљиву за ову компоненту. Важно: подвлака се може користити само у destructuring declaration, али не у конструктору data class. Ако се прескаче неколико компонената заредом, свакој одговара сопствена подвлака.
За класе без модификатора data може се ручно дефинисати componentN(), додавањем кључне речи operator. Ово омогућава коришћење destructuring declaration са било којом класом, укључујући спољне, за које се изворни код не може мијењати — довољно је написати екстензиону функцију са operator. Овај приступ је посебно корисан за библиотечке класе и класе из Java кода које немају аутоматске componentN().
class Rect(val width: Int, val height: Int)
operator fun Rect.component1(): Int = width
operator fun Rect.component2(): Int = height
// Za Java klasu sa getterima
operator fun Dimension.component1(): Int = width
operator fun Dimension.component2(): Int = height
fun main() {
val rect = Rect(1920, 1080)
val (w, h) = rect
println("Rezolucija: ${w}x${h}")
}
У примјеру Rect — обична класа без data. Екстензионе функције са operator fun component1() = width и component2() = height додају подршку за деструктуризацију. Слично за java.awt.Dimension: operator екстензија на Dimension омогућава да се разложи на width и height. Ограничење: максималан број компонената за destructuring declaration је 5. У теорији може се дефинисати component6() и више, али Kotlin неће генерисати одговарајућу синтаксу за 6+ промењљивих у заградама.
Често постављана питања
Да, свака data class аутоматски добија componentN() за сва својства примарног конструктора. Својства декларисана у тијелу класе (кроз конструктор без val/var) не генеришу componentN().
Ако у val (a, b, c) = obj објекат има само двије component функције, компилатор ће дати грешку. Ако је промењљивих мање (val (a) = pair), Kotlin ће позвати само component1() и игнорисати component2() — грешка се неће појавити.
Да, Map.Entry подржава деструктуризацију: val (key, value) = map.entries.first(). За цео Map одједном деструктуризација не ради — само елемент по елемент, у for петљи или преко итератора.
Да, Kotlin подржава деструктуризацију у параметрима ламбде: map.forEach { (k, v) -> ... }. За data class у параметрима ламбде потребно је додати угњеждене заграде око параметра.
Kotlin подржава до 5 промењљивих у destructuring declaration. Ако је потребно разложити више од пет својстава, спојите их у угњеждене data class или користите Pair/Triple унутар једне промењљиве.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође