1

I have a data class namely:

data class Entry(var name: String, var address: String, var phoneNo: String,
                 private val amt: String, var remark: String)

And I have a String Array: val data = arrayOf("x", "y", "z", "a", "b")

I'd like to pass the data array as a parameter when creating a new instance of Entry. I don't want to do it like this: val entry = Entry(data[0], data[1], data[2], data[3], data[4])

I've tried using the spread operator: Entry(*data) but it gives me an error saying the spread operator is not allowed here. This is because the parameter isn't a vararg. Also, note that varargs aren't allowed in the constructor of data classes.

Is there any way in Kotlin to spread an array to non-variadic functions (functions with a fixed number of arguments), especially if you know that the length of that array will always be the same?

I haven't found an answer to this yet after various searches. Could use some help. Thanks.

Edit: Collections in Kotlin do have component1(), component2()... methods all the way upto component5() for the first 5 elements of the array/list. So this allows one to do a destructuring assignment: val (a, b, c, d, e) = data. And then you can pass them on to the function/constructor: Entry(a, b, c, d, e).

But this is only half a solution because you're limited to the first 5 elements and it's still more verbose than a simple spread operator.

3
  • You may think you know, but the compiler doesn't trust you and can't prove you right. A slight help can be a destructuring assignment. Commented Apr 18, 2018 at 6:49
  • What is a destructuring argument? Could you provide it in answer form? Commented Apr 18, 2018 at 6:51
  • You could use delegate to construct object from map. More info: kotlinlang.org/docs/reference/… Commented Apr 18, 2018 at 7:01

2 Answers 2

1

I think your best recourse is to make your constructors private and rely on factory methods instead. Constructors should generally be treated as a lower-level feature that just does simple initialization from given values.

So declare a variadic factory method that has all the boilerplate of shoveling the data from the array over to the constructor. You may use the destructuring assignment to somewhat improve the looks of your code.

Note that there's nothing preventing you from declaring additional Array.componentN as extension functions:

fun entry(args: Array<String>) = args.let {
    (name, address, phoneNo, amt, remark, oneMore) -> 
    Entry(name, address, phoneNo, amt, remark, oneMore)
}

operator fun <T> Array<T>.component6() = get(5)
Sign up to request clarification or add additional context in comments.

Comments

0

You may create extension fun

inline fun Array<String>.toEntry() = Entry(
    this[0],
    this[1],
    this[2],
    this[3],
    this[4]
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.