Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Kotlin Destructuring Declarations: Unpacking Objects into Variables

Tech May 30 21

Destructuring declarations provide a concise way to extract multiple values from an object and assign them to separate variables.

val (name, age) = person

This syntax declares two new variables—name and age—in a single statement. Each can be used independently afterward:

println(name)
println(age)

Under the hood, the compiler trenslates this into calls to componentN() functions:

val name = person.component1()
val age = person.component2()

These component functions follow Kotlin’s operator conventions—similar to how +, *, or for loops rely on specific named functions. To be usable in destructuring, each componentN() must be marked with the operator modifier.

Destructuring also works inside for loops. For example:

for ((code, description) in items) {
    println("$code: $description")
}

Here, code receives the result of items[i].component1(), and description receives items[i].component2().

Returning Multiple Values from Functions

Data classes are ideal for returning grouped results beecause they automatically generate componentN() functions:

data class ApiResult(val data: String, val httpCode: Int)

fun fetchResponse(): ApiResult {
    return ApiResult("Success", 200)
}

val (payload, code) = fetchResponse() // Destructuring in action

While Pair<String, Int> could serve the same purpose, domain-specific data classes improve readability and type safety.

Destructuring Maps

Iterating over maps becomes more expressive with destructuring:

for ((key, value) in configurationMap) {
    process(key, value)
}

This works because Kotlin’s standard library provides extension functions like:

operator fun <K, V> Map<K, V>.iterator(): Iterator<Map.Entry<K, V>> = entrySet().iterator()
operator fun <K, V> Map.Entry<K, V>.component1(): K = key
operator fun <K, V> Map.Entry<K, V>.component2(): V = value

Ignoring Components with Underscores

When only some parts of a destructured value are needed, replace unused names with _:

val (_, errorCode) = performOperation()

No component1() call occurs in this case—the compiler skips it entirely.

Destructuring in Lambda Parameters

Lambda expressions support destructuring directly in thier parameter lists:

// Without destructuring
map.mapValues { entry -> "${entry.value.toUpperCase()}" }

// With destructuring
map.mapValues { (key, value) -> "$value!" }

You can mix destructured and regular parameters:

listOfPairs.map { (first, second), index -> "$first-$second@$index" }

Unused components may also be replaced by underscores inside lambdas:

map.filterKeys { (_, value) -> value.isNotEmpty() }

Type annotations can apply to the entire destructured parameter or individual components:

map.mapValues { (_, value): Map.Entry<String, String> -> value.uppercase() }
map.mapValues { (_, value: String) -> value.trim() }
Tags: kotlin

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Comprehensive Guide to Hive SQL Syntax and Operations

This article provides a detailed walkthrough of Hive SQL, categorizing its features and syntax for practical use. Hive SQL is segmented into the following categories: DDL Statements: Operations on...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.