Destructuring declaration — what it is, syntax and usage in Kotlin

Author: IT Sectr Published: 2026-06-23 Reading time: 7 min

Destructuring declaration is a Kotlin feature that lets you decompose an object into multiple variables in a single expression. The val (name, age) = user construct simultaneously declares two variables, assigning them values from the object’s components. According to the Kotlin documentation (2026), destructuring reduces code volume when working with data classes by 30–50%. Destructuring declaration makes code more concise and readable.

Key Takeaways

  • Destructuring declaration — syntax val (a, b) = obj for decomposing an object into variables
  • ComponentN() — functions component1(), component2(), component3() and so on, called automatically
  • Data class automatically generates componentN() for all properties declared in the primary constructor
  • Pair and Triple — standard classes with built-in destructuring for two and three values
  • Map.Entry — supports destructuring into key and value for convenient iteration

What is destructuring declaration?

Destructuring declaration is a Kotlin syntactic construct that allows you to decompose a class instance into multiple variables in a single expression. The left side contains a list of variables in parentheses, the right side contains the object being decomposed. Kotlin automatically calls the corresponding componentN() function for each variable, where N is the ordinal number of the variable in the parentheses.

Destructuring declaration is most commonly used with data classes. The Kotlin compiler automatically generates component1(), component2() and so on for each data class — based on the number of properties in the primary constructor. For regular classes without the data modifier, componentN() are not generated, but they can be defined manually as operator functions with the operator keyword.

Destructuring declaration has become a popular pattern due to its ability to simplify code when working with collections of pairs, function results, and Map iteration. Instead of writing person.firstName, person.lastName, the developer writes val (firstName, lastName) = person. This reduces the number of lines and improves readability, especially in loops and lambdas.

How does destructuring work in Kotlin?

When encountering the val (a, b) = obj construct, the Kotlin compiler generates the following code: val a = obj.component1(); val b = obj.component2(). If the variables are declared with var, var assignments are generated. The type of each variable is inferred from the return type of the corresponding componentN() function. This means that destructuring declaration is fully type-safe and checked at compile time.

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

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

    // Destructuring: component1(), component2(), component3()
    val (firstName, lastName, age) = person
    println("$firstName $lastName, $age years old")
}

In the listing, Person is a data class with three properties. Kotlin generates component1() → firstName, component2() → lastName, component3() → age. The expression val (firstName, lastName, age) = person calls these functions and assigns the results. Importantly: variable names do not need to match property names — the compiler only looks at the order of componentN() and their types. You can decompose only the first N properties, ignoring the rest.

Destructuring data classes and standard types

Data classes are the primary candidates for destructuring declaration. Each data class automatically gets componentN() for all properties of the primary constructor. The order of componentN() corresponds to the order of property declarations. This means that when you change the order of fields in a data class, the order of variables in destructuring changes as well — which can lead to subtle bugs.

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

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

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

Pair and Triple are standard classes with built-in destructuring for two and three components. Pair is often used as a return type for functions that need to return two related values without creating a separate data class. In a for loop over Map.Entry, the (k, v) = entry construct destructures the key and value via component1() and component2(). This is the standard pattern for iterating over a Map in Kotlin, completely replacing explicit key and value calls.

Underscore for unused variables

If some components are not needed during destructuring, Kotlin allows you to replace them with an underscore _. This improves readability — the reader immediately sees that the component is being ignored. Additionally, using _ prevents accidental access to an uninitialized variable: the compiler does not create any variable for _, eliminating warnings about unused variables.

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

In the listing, Order has four properties, but the loop only needs id and amount. The underscore in place of customerName tells the compiler “skip component2()”. Kotlin does not call component2() and does not create a variable for this component. Important: underscores can only be used in destructuring declarations, not in the data class constructor. If multiple consecutive components are skipped, each one gets its own underscore.

Creating componentN() for custom classes

For classes without the data modifier, you can manually define componentN() by adding the operator keyword. This allows you to use destructuring declaration with any class, including third-party classes whose source code cannot be modified — simply write an extension function with operator. This approach is especially useful for library classes and Java classes that do not have automatic componentN().

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

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

// For Java class with 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("Resolution: ${w}x${h}")
}

In the example, Rect is a regular class without data. Extension functions with operator fun component1() = width and component2() = height add destructuring support. Similarly for java.awt.Dimension: an operator extension on Dimension allows decomposing it into width and height. Limitation: the maximum number of components for destructuring declaration is 5. In theory you can define component6() and above, but Kotlin will not generate the corresponding syntax for 6+ variables in parentheses.

Frequently Asked Questions

Does every data class support destructuring?

Yes, every data class automatically gets componentN() for all properties of the primary constructor. Properties declared in the class body (using constructor parameters without val/var) do not generate componentN().

What happens if the number of variables doesn’t match?

If val (a, b, c) = obj has an object with only two component functions, the compiler will throw an error. If there are fewer variables (val (a) = pair), Kotlin will only call component1() and ignore component2() — no error will occur.

Can you destructure a Map without a loop?

Yes, Map.Entry supports destructuring: val (key, value) = map.entries.first(). Destructuring does not work on the entire Map at once — only element by element, in a for loop or via an iterator.

Does destructuring work in lambdas?

Yes, Kotlin supports destructuring in lambda parameters: map.forEach { (k, v) -> ... }. For data classes in lambda parameters, you need to add nested parentheses around the parameter.

What is the maximum size of destructuring?

Kotlin supports up to 5 variables in a destructuring declaration. If you need to decompose more than five properties, combine them into nested data classes or use Pair/Triple inside a single variable.

Summary

  • Destructuring declaration — syntax val (a, b) = obj, decomposing an object into multiple variables in a single expression
  • ComponentN() — functions component1(), component2(), ... called automatically by the compiler during destructuring
  • Data class automatically generates componentN() for all properties of the primary constructor
  • Pair and Triple — standard classes with built-in destructuring for 2 and 3 components
  • Underscore _ replaces unused components without creating a variable
  • Operator componentN() in extension functions adds destructuring to any class, including Java
  • Map.Entry in a for loop ((k, v) in map) — standard idiomatic Kotlin pattern for iterating over a dictionary

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also