I am looking for a clean way to create destructurable objects in-line. kotlin.Pair
and kotlin.Triple
cover a lot of use cases, but sometimes there are more objects that are needed to be passed.
One sample use case is RX's zip
function, where the results of several I/O calls need to be mapped into another object:
Single .zip(repositoryA.loadData(someId), repositoryB.loadData(someId), repositoryC.loadAll(), repositoryD.loadAll()), { objectA, objectB, objectsC, objectsD -> /*some Kotlin magic*/ } ) .map { (objectA, objectB, objectsC, objectsD) -> /*do the mapping*/ }
I am trying to figure out what would go in the "some Kotlin magic" part. If there were only 3 repositories, it would be
Triple(objectA, objectB, objectsC)
Do I need to create a new data class for this, and for any n-tuple case, or is there another way?
For Android developers who are making the transition from Java to Kotlin one of the more interesting features that you will eventually encounter are destructuring declarations. Destructuring allows you to break an object up into a number of variables.
What is Triple? Kotlin language provides a simple datatype to store three values in a single instance. This can be done using a data class known as Triple. It is a simple generic class that stores any three values, there is no valuable meaning of the relationship between the three values.
If you want to skip a variable or element in destructuring declarations, then you can use underscore instead of the variable name. As a result, Kotlin won't call the component function for those unused variables. For example, we need only the 1st, 5th and 6th elements in the list.
To create a Pair object, call the class constructor Pair(first: A, second: B) . A and B in the constructor signature signify that you are not restricted to a particular type, and you can take advantage of Kotlin's generics features here, e.g. val rect = Pair<Int, Long>(90, 70000) .
Let's see how destructuring works:
Kotlin defines a convention for this, i.e. componentX()
operator
functions are an example of the principle of conventions used in Kotlin in many places. These componentX()
functions are used by the compiler for the initialization of variables in destructuring declarations.
For example in Pair<A,B>
these functions look as follows:
operator fun component1(): A = first operator fun component2(): B = second
As you can see these are operators
, specially handled functions. These componentX()
functions can be provided by the developer and will automatically be produced by the compiler for data
classes. Pair
also is such a data
class btw.
Thus, just go ahead and use data
classes whenever you need more than a Triple
.
For example, a class MultiComponent
defined as this:
data class MultiComponent(val x: Int, val y: Int, val z: Int, val a: Int, val b: Int, val c: Int)
will be compiled to a class with functions component1()
, component2()
, ..., component6()
and can be used in destructuring declarations:
val (q, w, e, r, t, z) = MultiComponent(1, 2, 3, 4, 5, 6)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With