Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to implement custom destructuring for non data class in Kotlin?

Tags:

kotlin

In Kotlin data classes can be destructured like so:

fun main(args: Array<String>) {
    val thing = Stuff(1, "Hi", true)
    val(thing1, thing2, thing3) = thing

    println(thing1)
}

data class Stuff(val thing1: Int, val thing2: String, val thing3: Boolean)

I could be misreading the docs, or maybe I just couldn't find an example, but I'm looking for a way to implement custom destructuring of non-data classes. Is this possible in Kotlin?

like image 682
zjuhasz Avatar asked Mar 02 '16 01:03

zjuhasz


People also ask

How to declare destructuring in Kotlin?

A destructuring declaration is compiled as the following code: 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.

What is a data class in Kotlin?

It is not unusual to create classes whose main purpose is to hold data. In such classes, some standard functionality and some utility functions are often mechanically derivable from the data. In Kotlin, these are called data classes and are marked with data: data class User(val name: String, val age: Int)

Is it possible to unpack a structure manually in Kotlin?

Obviously, you can unpack the structure manually: But that's clunky. Is there a way to do that more elegantly? I don't see anything in the docs on the subject. Show activity on this post. Show activity on this post. You can vote for them. Destructuring for lambda arguments was implemented in Kotlin 1.1. Show activity on this post.

How do I return two things from a function in Kotlin?

Assume that you need to return two things from a function - for example, a result object and a status of some sort. A compact way of doing this in Kotlin is to declare a data class and return its instance: data class Result(val result: Int, val status: Status) fun function(...):


2 Answers

I was able to make this work like this:

fun main(args : Array<String>) {
    val person = Person("first", "last")
    val(param1, param2) = person
    println(param1)
    println(param2)
}

class Person(val firstName: String, val lastName: String) {
    operator fun component1() = firstName
    operator fun component2() = lastName
}
like image 92
AndroidEx Avatar answered Dec 17 '22 11:12

AndroidEx


Destructuring is performed by calling functions component1, component2, component3 etc, on the instance being destructured.

These functions can be either member functions declared inside your class or extension functions. Also component functions must have operator keyword to indicate they are to satisfy a convention, namely destructuring one.

For data classes compiler generates corresponding component function for each property of data class declared in its primary constructor.

An example of class with custom component functions:

class Result(val e: Exception?) {
    val hasFailed = e != null

    operator fun component1(): Exception? = e
    operator fun component2(): Boolean = hasFailed
}

val (e, hasFailed) = Result(RuntimeException())
like image 44
Ilya Avatar answered Dec 17 '22 10:12

Ilya