Destructuring declaration — är Kotlins förmåga att dela upp ett objekt i flera variabler i ett enda uttryck. Konstruktionen val (name, age) = user deklarerar samtidigt två variabler och tilldelar dem värden från objektets komponenter. Enligt Kotlin-dokumentationen (2026) minskar destrukturering kodvolymen vid arbete med data class med 30–50%. Destructuring declaration gör koden mer koncis och läsbar.
Huvudpunkter
Destructuring declaration (destrukturerande deklaration) — är en syntaktisk konstruktion i Kotlin som gör det möjligt att dela upp en klassinstans i flera variabler i ett enda uttryck. Den vänstra sidan innehåller listan över variabler inom parentes, den högra sidan — objektet som ska delas upp. Kotlin anropar automatiskt för varje variabel motsvarande funktion componentN(), där N är variabelns ordningsnummer inom parentes.
Destructuring declaration används oftast med data class. Kotlin-kompilatorn genererar automatiskt för data class funktionerna component1(), component2() och så vidare — enligt antalet egenskaper i den primära konstruktorn. För vanliga klasser utan modifieraren data genereras inte componentN(), men de kan definieras manuellt som operatorfunktioner med nyckelordet operator.
Destructuring declaration har blivit ett populärt mönster tack vare sin förmåga att förenkla kod vid arbete med samlingar av par, funktionsresultat och genomgång av Map. Istället för att skriva person.firstName, person.lastName skriver utvecklaren val (firstName, lastName) = person. Detta minskar antalet rader och ökar läsbarheten, särskilt i loopar och lambdor.
När kompilatorn stöter på konstruktionen val (a, b) = obj genererar den koden: val a = obj.component1(); val b = obj.component2(). Om variabler är deklarerade med var genereras var-tilldelningar. Typen av varje variabel härleds från returtypen för motsvarande funktion componentN(). Detta innebär att destructuring declaration är helt typsäker och kontrolleras vid kompilering.
data class Person(val firstName: String, val lastName: String, val age: Int)
fun main() {
val person = Person("Alice", "Smith", 30)
// Destrukturering: component1(), component2(), component3()
val (firstName, lastName, age) = person
println("$firstName $lastName, $age år gammal")
}
I listningen Person — data class med tre egenskaper. Kotlin genererar component1() → firstName, component2() → lastName, component3() → age. Uttrycket val (firstName, lastName, age) = person anropar dessa funktioner och tilldelar resultaten. Viktigt: variabelnamn kan skilja sig från egenskapsnamn — kompilatorn tittar bara på ordningen på componentN() och deras typer. Man kan bara dela upp de första N egenskaperna och ignorera resten.
Data class — den främsta kandidaten för destructuring declaration. Varje data class får automatiskt componentN() för alla egenskaper i den primära konstruktorn. Ordningen på componentN() motsvarar ordningen för egenskapsdeklaration. Detta innebär att när fältordningen ändras i data class ändras ordningen på variablerna i destruktureringen — vilket kan leda till osynliga buggar.
// Pair-destrukturering
val pair = Pair("key", 42)
val (key, value) = pair
println("$key -> $value")
// Triple-destrukturering
val triple = Triple("A", "B", "C")
val (first, second, third) = triple
// Map.Entry i loop
val map = mapOf("a" to 1, "b" to 2)
for ((k, v) in map) {
println("$k = $v")
}
Pair och Triple — standardklasser med färdig destrukturering för två och tre komponenter. Pair används ofta som returtyp för funktioner som behöver returnera två relaterade värden utan att skapa en separat data class. I en for-loop över Map.Entry destrukturerar konstruktionen (k, v) = entry nyckeln och värdet via component1() och component2(). Detta är standardmönstret för att gå igenom Map i Kotlin, som helt ersätter explicita anrop av key och value.
Om vissa komponenter inte behövs vid destrukturering tillåter Kotlin att de ersätts med en understrykning _. Detta förbättrar läsbarheten — läsaren ser omedelbart att komponenten ignoreras. Dessutom förhindrar användningen av _ oavsiktlig åtkomst till en oinitierad variabel: kompilatorn skapar ingen variabel för _, vilket eliminerar varningar om oanvända variabler.
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("Order $id: $amount")
}
}
I listningen har Order fyra egenskaper, men i loopen behövs bara id och amount. Understrykningen i stället för customerName säger till kompilatorn ”hoppa över component2()”. Kotlin anropar inte component2() och skapar ingen variabel för denna komponent. Viktigt: understrykning kan endast användas i destructuring declaration, men inte i data class-konstruktorn. Om flera komponenter hoppas över i rad har var och en sin egen understrykning.
För klasser utan modifieraren data kan man manuellt definiera componentN() genom att lägga till nyckelordet operator. Detta gör det möjligt att använda destructuring declaration med vilken klass som helst, inklusive externa klasser vars källkod inte kan ändras — det räcker att skriva en tilläggsfunktion med operator. Detta tillvägagångssätt är särskilt användbart för biblioteksklasser och klasser från Java-kod som inte har automatiska componentN().
class Rect(val width: Int, val height: Int)
operator fun Rect.component1(): Int = width
operator fun Rect.component2(): Int = height
// För Java-klass med getters
operator fun Dimension.component1(): Int = width
operator fun Dimension.component2(): Int = height
fun main() {
val rect = Rect(1920, 1080)
val (w, h) = rect
println("Upplösning: ${w}x${h}")
}
I exemplet Rect — en vanlig klass utan data. Tilläggsfunktioner med operator fun component1() = width och component2() = height lägger till stöd för destrukturering. Likaså för java.awt.Dimension: en operator-tillägg på Dimension gör det möjligt att dela upp det i width och height. Begränsning: det maximala antalet komponenter för destructuring declaration är 5. I teorin kan man definiera component6() och högre, men Kotlin kommer inte att generera motsvarande syntax för 6+ variabler inom parentes.
Vanliga frågor
Ja, varje data class får automatiskt componentN() för alla egenskaper i den primära konstruktorn. Egenskaper deklarerade i klasskroppen (via konstruktor utan val/var) genererar inte componentN().
Om i val (a, b, c) = obj objektet bara har två component-funktioner, ger kompilatorn ett fel. Om variablerna är färre (val (a) = pair), anropar Kotlin bara component1() och ignorerar component2() — inget fel uppstår.
Ja, Map.Entry stödjer destrukturering: val (key, value) = map.entries.first(). För hela Map på en gång fungerar inte destrukturering — bara element för element, i en for-loop eller via en iterator.
Ja, Kotlin stödjer destrukturering i lambdaparametrar: map.forEach { (k, v) -> ... }. För data class i lambdaparametrar måste man lägga till nästade parenteser runt parametern.
Kotlin stödjer upp till 5 variabler i destructuring declaration. Om du behöver dela upp fler än fem egenskaper, kombinera dem i nästade data class eller använd Pair/Triple inuti en variabel.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också