13

I have a class Person:

class Person(val name: String, val age: Int)

I want to use Destructuring declaration with Parent like this:

val (name, age) = Person("name", 22)

but I get this error:

Destructuring declaration initializer of type Person must have a 'component1()' function Destructuring declaration initializer of type Person must have a 'component2()' function

humazed
  • 74,687
  • 32
  • 99
  • 138

3 Answers3

27

We need to declare Person as data class.

data class Person(val name: String, val age: Int)

it wasn't very clear in the docs but for official ref:

https://kotlinlang.org/docs/reference/multi-declarations.html#example-returning-two-values-from-a-function

from Marko Topolnik comment:
if for some reason someone can't use data class it's not mandatory. You can declare the functions component1() and component2() in any class.

humazed
  • 74,687
  • 32
  • 99
  • 138
  • 10
    It's not mandatory to declare it as a data class. You can declare the functions `component1()` and `component2()` in any class. – Marko Topolnik Jan 16 '18 at 18:32
  • 2
    yes, but the whole point of using Destructuring declaration is to have a concise code, and using data classes is the easiest way. but if for some reason someone can't use data class they can resort to `component1()` and `component2()` solution – humazed Jan 16 '18 at 18:35
  • 2
    That's exactly my point. You don't _have_ to use a data class if that's not appropriate. – Marko Topolnik Jan 16 '18 at 18:46
4

It's very helpful if you simply let the IDE do some work for you. Here are the suggestions given by IntelliJ IDEA that help to fix the error:

enter image description here

It basically lists all alternatives: data class is probably the easiest one. You can also create the corresponding componentX functions manually, which are otherwise automatically generated for data classes. In this SO thread, I gave some information on this kind of function.

As to your example, I'll show how to provide the componentX functions by using extension functions. This approach is especially useful whenever you're working with classes that you cannot modify yourself. It's that simple:

private operator fun Person.component1() = name
private operator fun Person.component2() = age
s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
3

The easiest way to solve this problem is to use a data class since data classes automatically declare componentN() functions (see the docs).

data class Person(val name: String, val age: Int)
val (name, age) = Person("name", 22) // OK

Sometimes you might not have access to the source code of a class you want to allow destructuring, so if for any reasons you are not allowed to use data classes, you can provide the componentX functions (component1 and component2 in this case) by using extension functions.

operator fun Person.component1() = name
operator fun Person.component2() = age
lmiguelvargasf
  • 63,191
  • 45
  • 217
  • 228