Destructuring Declarations in Kotlin
Destructuring declarations is a Kotlin feature that gives you a tool for easily extracting data from a collection in a simple and clean way. By arjuna sky kok.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Destructuring Declarations in Kotlin
25 mins
- Getting Started
- Destructuring Declarations
- Destructuring Declarations of a Pair, Array and Map
- Destructuring Declarations of A Pair
- Destructuring Declarations of An Array
- Component1, Component2, …, ComponentN
- Omitting Variables in Destructuring Declarations
- Common Use Case of Destructuring Declarations
- Destructuring Declarations of A Map
- Destructuring Declarations in a Lambda Function
- Destructuring Declarations in Lambda
- The Gotcha in Destructuring A Data Class
- Making A Class Support Destructuring Declarations
- Where to Go From Here?
The Gotcha in Destructuring A Data Class
One of the most common data types you’ll extract using destructuring declarations is a data class. However, you must be careful because the destructuring declarations of a data class are positional-based, not named-based.
Look at this data class instance and example of the wrong way to use destructuring declarations:
data class Founder(var name: String, var cryptocurrency: String, var country: String)
val founder = Founder("Vitalik", "Ethereum", "Canada")
// val (cryptocurrency, name, country) = founder
cryptocurrency
has the value Vitalik
, not Ethereum
.
To prove this is the case, uncomment:
// val (cryptocurrency, name, country) = founder
Then add println
to print the value. The line will look like this:
val (cryptocurrency, name, country) = founder
println(cryptocurrency)
Build and run. You can see the value of cryptocurrency
.
As you can see, cryptocurrency
indeed has the value Vitalik
.
To have the correct values, you need to realize the destructuring declarations of a data class are positional-based.
Now, undo the last change or delete the lines you added before. The line you modified will look like this:
// val (cryptocurrency, name, country) = founder
Then replace TODO 7
with:
val (name, cryptocurrency, country) = founder
println("$name, $cryptocurrency, $country")
Build and run. You can see the value of name
, cryptocurrency
and country
.
Now, name
, cryptocurrency
and country
refer to the proper values.
If you’re annoyed by the maximum of five elements in destructuring declarations of a collection, good news! The data class doesn’t have that limitation.
Even if your data class has twenty components, you can extract all of them with destructuring declarations.
However, you can’t provide an explicit implementation for the componentN
in the data class. So, if you want to prank your colleagues by overriding component2
to return the third element and component3
to return the first element, you can forget it. Fortunately, the Kotlin designers put in restrictions to protect your colleagues from your cruel prank. :]
But what if you persist in your attempt to prank your colleagues? That’s where the custom class can help you.
Making A Class Support Destructuring Declarations
What if you want to add support for destructuring declarations of more than five elements on a class? Look at the definition of Cryptocurrencies
:
class Cryptocurrencies {
operator fun component1() : String = "Bitcoin"
operator fun component2() : String = "Ethereum"
operator fun component3() : String = "Binance Coin"
operator fun component4() : String = "Tether"
operator fun component5() : String = "XRP"
operator fun component6() : String = "Uniswap"
}
Remember component5
which you used to extract the fifth element from an array? If you want to extract the sixth element from a class, define component6
.
The method must be an operator method. If you want to extract twenty elements from a class, you need to define component1
to component20
.
Replace TODO 8
with:
val (bitcoin, ethereum, binanceCoin, tether, xrp, uniswap) = Cryptocurrencies()
println("$bitcoin, $ethereum, $binanceCoin, $tether, $xrp, $uniswap")
Build and run.
As you can see now, you extracted six elements from the instance of a class.
Remember that you wanted to prank your colleagues? You can override component3
to return something annoying. For example, you could do something like this:
//operator fun component3() : String = "Binance Coin"
operator fun component3() : String {
val current = LocalDateTime.now()
if (current.monthValue % 2 == 0) {
return "Binance Coin"
} else {
return "Doge"
}
}
If your colleagues use this class, they’ll get different data when they extract component3
depending on whether the current month is odd or even. Don’t forget to import java.time.LocalDateTime
first if you’re serious with this prank.
Where to Go From Here?
You can download the complete project by clicking Download Materials at the top or bottom of this tutorial. In this tutorial you learned:
- What are destructuring declarations and how to use them.
- How to use destructuring declarations in collections: Pairs, Arrays and Maps.
- Destructuring declarations in lambda functions.
- The use of destructuring declarations in data classes and custom classes.
This project is only the beginning: there’s more to explore. Why not add support for destructuring declarations of more than five elements of an array or list? You can do it by writing operator methods.
You learned about the destructuring declarations in Kotlin. But you’ve only scratched the surface of the Kotlin programming language. If you want to know more about Kotlin, read our book Kotlin Apprentice, which has more info about Kotlin.
If you have any suggestions, questions or anything else, join the discussion below.