1. Overview

In this tutorial, we’ll introduce the concept of Destructuring Declarations in Kotlin, and take a look at how it can be used.

If you want to learn more about Kotlin, check out this article.

2. Destructuring Declarations

This concept consists of treating objects as a set of separate variables.

2.1. Objects

Destructuring an object into multiple variables can be convenient:

val person = Person(1, "Jon Snow", 20)
val(id, name, age) = person

With this, we’ve created three new variables:

println(id)     //1
println(name)   //Jon Snow
println(age)    //20

A destructuring declaration is compiled as the following code:

val id = person.component1();
val name = person.component2();
val age = person.component3();

In order to use destructuring declaration, we need to make sure either the component is marked with the operator or the class is marked with the data keywords.

For more on Data Classes in Kotlin, don’t forget to check this article.

2.2. Return Types

Destructuring declarations can also be used when working with return values:

fun getPersonInfo() = Person(2, "Ned Stark", 45)
val(id, name, age) = getPersonInfo()

Or let’s say we need to return two values from a function:

fun twoValuesReturn(): Pair<Int, String> {
    // ...
    return Pair(1, "success")

val (result, status) = twoValuesReturn()

2.3. Collections and For-loops

Iterate a collection with for-loops can be done with destructuring declarations, like this:

for ((a, b) in collection) { ... }

The variables a and b are assigned values returned by component1() and component2() methods – which return the first two elements in a collection.

However, in a Map, the variables would be key and value, respectively:

var map: HashMap<Int, Person> = HashMap()

map.put(1, person)

for((key, value) in map){
    println("Key: $key, Value: $value")

2.4. Underscore and Destructuring in Lambdas

In case we don’t need all values obtained in a destructuring declaration, we can use underscore instead of the variable name:

val (_, name, age) = person

Or, if not needed fields are at the end, we can omit them at all:

val (id, name) = person

We can also use the destructuring declarations syntax for lambda parameters, as long as it is a type with the appropriate componentN functions:

map.mapValues { entry -> "${entry.value}!" }
map.mapValues { (key, value) -> "$value!" }

Be aware of the difference between declaring two parameters and declaring a destructuring pair:

{ a -> ... } // one parameter
{ a, b -> ... } // two parameters
{ (a, b) -> ... } // a destructured pair
{ (a, b), c -> ... } // a destructured pair and another parameter

3. Conclusion

In this quick article, we’ve approached Destructuring Declarations in Kotlin, with its many usages and particularities.

To learn more about Kotlin, definitely, check out our other articles such as Overview of Kotlin Collections API and the already mentioned Data Classes in Kotlin.

And, as always, the full implementation of these examples can be found in our GitHub project.