Kotlin Destructuring
Destructuring lets you unpack an object into multiple variables in one statement. Instead of writing several lines to extract each field, you write one line and get all the pieces at once. Kotlin supports destructuring for data classes, Pairs, Triples, lists, maps, and loop variables.
Destructuring a Data Class
data class Point(val x: Int, val y: Int)
data class Employee(val name: String, val dept: String, val salary: Double)
fun main() {
val point = Point(10, 25)
val (x, y) = point
println("x=$x, y=$y") // x=10, y=25
val emp = Employee("Alice", "Tech", 90000.0)
val (name, dept, salary) = emp
println("$name works in $dept and earns ₹$salary")
}How Destructuring Works
data class Point(val x: Int, val y: Int)
val (x, y) = Point(10, 25)
Kotlin generates componentN() functions automatically for data classes:
component1() → x → 10
component2() → y → 25
The destructuring line is equivalent to:
val x = point.component1()
val y = point.component2()
Destructuring a Pair and Triple
val pair = Pair("Kotlin", 2016)
val (language, year) = pair
println("$language released in $year")
val triple = Triple("Alice", 30, "Engineer")
val (personName, age, role) = triple
println("$personName, $age, $role")Skipping Components with Underscore
data class User(val id: Int, val name: String, val email: String, val role: String)
val user = User(1, "Bob", "bob@mail.com", "admin")
// Only need name and role — skip id and email
val (_, name, _, role) = user
println("$name is a $role")Destructuring in for Loops
val scores = mapOf("Alice" to 92, "Bob" to 88, "Carol" to 95)
for ((student, score) in scores) {
println("$student scored $score")
}
val pairs = listOf(Pair("Jan", 150), Pair("Feb", 180), Pair("Mar", 200))
for ((month, sales) in pairs) {
println("$month: $sales units")
}Output:
Alice scored 92
Bob scored 88
Carol scored 95
Jan: 150 units
Feb: 180 units
Mar: 200 unitsDestructuring with withIndex
val cities = listOf("Delhi", "Mumbai", "Chennai")
for ((index, city) in cities.withIndex()) {
println("$index → $city")
}Destructuring in Lambda Parameters
val inventory = mapOf("Pen" to 500, "Book" to 200, "Bag" to 80)
// Destructure map entries directly in the lambda
inventory.forEach { (item, qty) ->
println("$item: $qty in stock")
}
val employees = listOf(
Pair("Alice", 90000),
Pair("Bob", 72000)
)
employees.map { (name, salary) -> "$name earns ₹$salary" }
.forEach { println(it) }Custom componentN() Functions
You can enable destructuring on your own non-data classes by adding operator fun componentN():
class Color(val r: Int, val g: Int, val b: Int) {
operator fun component1() = r
operator fun component2() = g
operator fun component3() = b
}
fun main() {
val color = Color(255, 128, 0)
val (red, green, blue) = color
println("R=$red G=$green B=$blue") // R=255 G=128 B=0
}Practical Example: Order Summary
data class OrderItem(val product: String, val qty: Int, val unitPrice: Double)
fun summarize(item: OrderItem): String {
val (product, qty, price) = item
return "$product × $qty = ₹${qty * price}"
}
fun main() {
val cart = listOf(
OrderItem("Laptop", 1, 75000.0),
OrderItem("Mouse", 2, 800.0),
OrderItem("Bag", 1, 1500.0)
)
cart.forEach { println(summarize(it)) }
val total = cart.sumOf { (_, qty, price) -> qty * price }
println("─────────────────")
println("Total: ₹$total")
}Output:
Laptop × 1 = ₹75000.0
Mouse × 2 = ₹1600.0
Bag × 1 = ₹1500.0
─────────────────
Total: ₹78100.0