Destructuring declaration — co to jest, składnia i zastosowanie w Kotlin

Autor: IT Sectr Opublikowano: 2026-06-23 Czas czytania: 7 min

Destructuring declaration — to możliwość Kotlina, aby rozłożyć obiekt na kilka zmiennych w jednym wyrażeniu. Konstrukcja val (name, age) = user jednocześnie deklaruje dwie zmienne, przypisując im wartości z komponentów obiektu. Według dokumentacji Kotlina (2026), destrukturyzacja zmniejsza ilość kodu przy pracy z data class o 30–50%. Destructuring declaration sprawia, że kod jest bardziej zwięzły i czytelny.

Najważniejsze

  • Destructuring declaration — składnia val (a, b) = obj do rozkładania obiektu na zmienne
  • ComponentN() — funkcje component1(), component2(), component3() i tak dalej, wywoływane automatycznie
  • Data class automatycznie generuje componentN() dla wszystkich właściwości zadeklarowanych w primary constructor
  • Pair i Triple — standardowe klasy z gotową destrukturyzacją dla dwóch i trzech wartości
  • Map.Entry — obsługuje destrukturyzację na key i value dla wygodnego przeglądania

Co to jest destructuring declaration?

Destructuring declaration (deklaracja destrukturyzująca) — to konstrukcja składniowa Kotlina, pozwalająca rozłożyć instancję klasy na kilka zmiennych w jednym wyrażeniu. Lewa strona zawiera listę zmiennych w nawiasach, prawa — rozkładany obiekt. Kotlin automatycznie wywołuje dla każdej zmiennej odpowiednią funkcję componentN(), gdzie N to numer porządkowy zmiennej w nawiasach.

Najczęściej destructuring declaration jest stosowana z data class. Kompilator Kotlina automatycznie generuje dla data class funkcje component1(), component2() i tak dalej — według liczby właściwości w konstruktorze pierwotnym. Dla zwykłych klas bez modyfikatora data componentN() nie są generowane, ale można je zdefiniować ręcznie jako funkcje operatorowe z kluczowym słowem operator.

Destructuring declaration stała się popularnym wzorcem dzięki swojej zdolności do upraszczania kodu podczas pracy z kolekcjami par, wynikami funkcji i przeglądaniem Map. Zamiast odwołania person.firstName, person.lastName programista pisze val (firstName, lastName) = person. Zmniejsza to liczbę wierszy i zwiększa czytelność, szczególnie w pętlach i lambdach.

Jak działa destrukturyzacja w Kotlin?

Przy napotkaniu konstrukcji val (a, b) = obj kompilator Kotlina generuje kod: val a = obj.component1(); val b = obj.component2(). Jeśli zmienne są zadeklarowane z var, generowane są przypisania var. Typ każdej zmiennej jest wnioskowany z typu zwracanego odpowiedniej funkcji componentN(). Oznacza to, że destructuring declaration jest w pełni bezpieczna typowo i sprawdzana na etapie kompilacji.

kotlin
data class Person(val firstName: String, val lastName: String, val age: Int)

fun main() {
    val person = Person("Alice", "Smith", 30)

    // Destrukturyzacja: component1(), component2(), component3()
    val (firstName, lastName, age) = person
    println("$firstName $lastName, $age lat")
}

W listingu Person — data class z trzema właściwościami. Kotlin generuje component1() → firstName, component2() → lastName, component3() → age. Wyrażenie val (firstName, lastName, age) = person wywołuje te funkcje i przypisuje wyniki. Ważne: nazwy zmiennych mogą nie pokrywać się z nazwami właściwości — kompilator patrzy tylko na kolejność componentN() i ich typy. Można rozłożyć tylko pierwsze N właściwości, ignorując pozostałe.

Destrukturyzacja data class i typów standardowych

Data class — główny kandydat dla destructuring declaration. Każdy data class automatycznie otrzymuje componentN() dla wszystkich właściwości konstruktora pierwotnego. Kolejność componentN() odpowiada kolejności deklaracji właściwości. Oznacza to, że przy zmianie kolejności pól w data class zmienia się kolejność zmiennych w destrukturyzacji — co może prowadzić do niezauważalnych błędów.

kotlin
// Destrukturyzacja Pair
val pair = Pair("key", 42)
val (key, value) = pair
println("$key -> $value")

// Destrukturyzacja Triple
val triple = Triple("A", "B", "C")
val (first, second, third) = triple

// Map.Entry w pętli
val map = mapOf("a" to 1, "b" to 2)
for ((k, v) in map) {
    println("$k = $v")
}

Pair i Triple — standardowe klasy z gotową destrukturyzacją na dwa i trzy komponenty. Pair jest często używany jako typ zwracany funkcji, które muszą zwrócić dwie powiązane wartości bez tworzenia osobnego data class. W pętli for po Map.Entry konstrukcja (k, v) = entry destrukturyzuje klucz i wartość przez component1() i component2(). Jest to standardowy wzorzec przeglądania Map w Kotlin, całkowicie zastępujący jawne wywołania key i value.

Podkreślenie dla nieużywanych zmiennych

Jeśli przy destrukturyzacji niektóre komponenty nie są potrzebne, Kotlin pozwala zastąpić je podkreśleniem _. Poprawia to czytelność — czytelnik od razu widzi, że komponent jest ignorowany. Ponadto użycie _ zapobiega przypadkowemu odwołaniu się do niezainicjalizowanej zmiennej: kompilator nie tworzy dla _ żadnej zmiennej, co eliminuje ostrzeżenia o nieużywanych zmiennych.

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("Zamówienie $id: $amount")
    }
}

W listingu Order ma cztery właściwości, ale w pętli potrzebne są tylko id i amount. Podkreślenie w miejscu customerName mówi kompilatorowi „pomiń component2()". Kotlin nie wywołuje component2() i nie tworzy zmiennej dla tego komponentu. Ważne: podkreślenia można używać tylko w destructuring declaration, ale nie w konstruktorze data class. Jeśli pomijanych jest kilka komponentów z rzędu, każdemu odpowiada własne podkreślenie.

Tworzenie componentN() dla własnych klas

Dla klas bez modyfikatora data można ręcznie zdefiniować componentN(), dodając kluczowe słowo operator. Pozwala to używać destructuring declaration z dowolną klasą, w tym zewnętrznymi, dla których nie można zmienić kodu źródłowego — wystarczy napisać funkcję rozszerzającą z operatorem. Takie podejście jest szczególnie przydatne dla klas bibliotecznych i klas z kodu Java, które nie mają automatycznych componentN().

kotlin
class Rect(val width: Int, val height: Int)

operator fun Rect.component1(): Int = width
operator fun Rect.component2(): Int = height

// Dla klasy Java z getterami
operator fun Dimension.component1(): Int = width
operator fun Dimension.component2(): Int = height

fun main() {
    val rect = Rect(1920, 1080)
    val (w, h) = rect
    println("Rozdzielczość: ${w}x${h}")
}

W przykładzie Rect — zwykła klasa bez data. Funkcje rozszerzające z operator fun component1() = width i component2() = height dodają obsługę destrukturyzacji. Podobnie dla java.awt.Dimension: operator rozszerzający na Dimension pozwala rozłożyć go na width i height. Ograniczenie: maksymalna liczba komponentów dla destructuring declaration — 5. W teorii można zdefiniować component6() i wyższe, ale Kotlin nie wygeneruje odpowiedniej składni dla 6+ zmiennych w nawiasach.

Często zadawane pytania

Czy każdy data class obsługuje destrukturyzację?

Tak, każdy data class automatycznie otrzymuje componentN() dla wszystkich właściwości konstruktora pierwotnego. Właściwości zadeklarowane w ciele klasy (przez konstruktor bez val/var) nie generują componentN().

Co się stanie przy niezgodności liczby zmiennych?

Jeśli w val (a, b, c) = obj obiekt ma tylko dwie funkcje component, kompilator zgłosi błąd. Jeśli zmiennych jest mniej (val (a) = pair), Kotlin wywoła tylko component1() i zignoruje component2() — błąd nie wystąpi.

Czy można destrukturyzować Map bez pętli?

Tak, Map.Entry obsługuje destrukturyzację: val (key, value) = map.entries.first(). Dla całej Map naraz destrukturyzacja nie działa — tylko element po elemencie, w pętli for lub przez iterator.

Czy destrukturyzacja działa w lambdach?

Tak, Kotlin obsługuje destrukturyzację w parametrach lambdy: map.forEach { (k, v) -> ... }. Dla data class w parametrach lambdy należy dodać zagnieżdżone nawiasy wokół parametru.

Jaki jest maksymalny rozmiar destrukturyzacji?

Kotlin obsługuje do 5 zmiennych w destructuring declaration. Jeśli trzeba rozłożyć więcej niż pięć właściwości, połącz je w zagnieżdżone data class lub użyj Pair/Triple wewnątrz jednej zmiennej.

Podsumowanie

  • Destructuring declaration — składnia val (a, b) = obj, rozkładająca obiekt na kilka zmiennych w jednym wyrażeniu
  • ComponentN() — funkcje component1(), component2(), ... wywoływane przez kompilator automatycznie przy destrukturyzacji
  • Data class automatycznie generuje componentN() dla wszystkich właściwości konstruktora pierwotnego
  • Pair i Triple — standardowe klasy z gotową destrukturyzacją na 2 i 3 komponenty
  • Podkreślenie _ zastępuje nieużywane komponenty bez tworzenia zmiennej
  • Operator componentN() w funkcjach rozszerzających dodaje destrukturyzację dowolnym klasom, w tym Java
  • Map.Entry w pętli for ((k, v) in map) — standardowy idiomatyczny wzorzec Kotlina do przeglądania słownika

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również