Kotlin Unpacking Params

Chetan Gupta
4 min readJul 31, 2019

Destructuring Declarations in Kotlin

De-structuring at its core a syntactic sugar to easily unpack parameters out of an object or array and declare local all in one shot.

Basically instead of doing this :

We get away with this :

What all we can use destructure?

you can destructure data class and Collections, you can also use them in other components such as in loops, lambdas, and return types.

Examples:

How to Blow Your Code with Destructuring?

Destructuring thou handy comes with its own quirks, see the code below.

if your familiar with Javascript/ECMA/TypeScript you would have guessed the code should have worked, we would have got third as “null”, in case of Kotlin something equivalent like “Unit”, “Nothing” or “String?” etc but here we get an error of “component3()” function? what is that?

Under the Hood!

In ECMA/TypeScript, destructuring comes in two forms: positional (for arrays and iterables) and by name (for objects).

In Kotlin, things are strongly-typed and thus unlike ECMA/TypeScript, which uses key-value/map-like encapsulation, there are full-encapsulation rules for objects, hence accessing the object by name isn’t applicable unless your using Reflection which is slow and inefficient.

Consequently, to support de-structuring, Kotlin team opted for limited use to only positional de-structuring for all use-case.

If you look at the explicit documentation, in Kotlin Collections they have added generic extensions as mentioned below:

operator fun <T> Array<out T>.component1(): T
operator fun ByteArray.component1(): Byte
operator fun ShortArray.component1(): Short
operator fun IntArray.component1(): Int
operator fun LongArray.component1(): Long
operator fun FloatArray.component1(): Float
operator fun DoubleArray.component1(): Double
operator fun BooleanArray.component1(): Boolean
operator fun CharArray.component1(): Char
operator fun <T> List<T>.component1(): T

Happy ending? #Spoiler nope!

As you see above these extensions only exist in the data class, so what of normal class?

As discussed above, destructing is positional here hence, unused components are still declared,

also, there is no default value available i.e you can’t do: (name, age = 13) in the case where age comes “null”.

Possible Deal Breaker!

Using positional data for representing a class, is not a good way for accessing its parameter, it doesn't provide any type/name check method to Android Studio/Lint to figure out if any refactoring is been done on the class and the points of destructing are also required to be refactored! i.e Ordering is part of the API contract! if you change your data class constructor arg reordering it will break.

So any solutions?

Yes ! and No!, Since destructing in Kotlin is limited you should consider using it in very specific cases, keeping in mind having maintainable code has higher priority than writing less boilerplate or syntactic sugar.

Destructuring Use-Cases

  • Using below trick you can enforce positionally destructing so even if contact breaks due to rearranging of members doesn't affect the destruct code.

also if you understand the use case here, it's better to use with(items) { ... } or items.apply { ... } the operator there than destructuring, but if you see yourself nesting with or apply just to access object params destructuring is a better approach.

  • Using for Loops in Collection : for((a,b) in collection) {...}
  • Returning Values from a Function :

The End.

Congratulation you made it till the end!. if you found anything interesting feel free to share in response. Happy Coding!

Follow me on Twitter and LinkedIn

further reading:

--

--

Chetan Gupta

Android & Kotlin Expert | https://chetangupta.net | Training & Technical writing for Bussiness contact https://t.me/ch810