1. Intro
As we know, we can add a vararg modifier to a method parameter which allows us to pass one or more values to that method.
However, these values must be passed individually. This also means that passing an array as-is for a vararg parameter isn’t allowed.
Let’s look at how we can get around that and convert a Kotlin array to a vararg parameter.
2. Spread Operator
Using the spread (*) operator in Kotlin, we can unpack a primitive array to its elements.
This opens up the possibility of indirectly passing an array to a function that needs a vararg parameter.
2.1. A Simple Example
Let’s take an example:
private fun concat(vararg strings: String): String {
return strings.fold("") { acc, next -> "$acc$next" }
}
Here, we have a simple function that accepts a number of strings and concatenates them.
We can use the spread operator to pass an array to this function:
val strings = arrayOf("ab", "cd")
assertTrue { concat(*strings) == "abcd" }
Note that we can only use typed arrays with the spread operator. However, we can always convert other collections to typed arrays and use them with the spread operator:
val listOfStrings = listOf("ab", "cd")
assertTrue { concat(*listOfStrings.toTypedArray()) == "abcd" }
2.2. Parameter Ordering
Interestingly, unlike Java, we can place the vararg at any position in Kotlin. It doesn’t have to be the last parameter in the function.
However, such a function should have default values for parameters that are not vararg. If that’s not possible, we can instead call them with named parameters:
private fun concat2(vararg strings: String, initialValue: String = "01"): String {
return strings.fold(initialValue) { acc, next -> "$acc$next" }
}
private fun concat3(vararg strings: String, initialValue: String): String {
return strings.fold(initialValue) { acc, next -> "$acc$next" }
}
assertTrue { concat2(*strings) == "01abcd" }
assertTrue { concat3(strings = *strings, initialValue = "01") == "01abcd" }
2.3. Combining Multiple Spread Operations
As in Java, we can only have a single vararg parameter for a function.
Although, it’s possible to pass multiple arrays to a single vararg parameter:
assertTrue { concat(*strings, "ef", *moreStrings) == "abcdefghij" }
3. Conclusion
There are multiple ways of converting a Kotlin array to a vararg parameter. Firstly, we can simply pass an array with a spread operator to the function call. It’s also possible to pass multiple arrays. Additionally, we can even combine literals and arrays to functions with vararg parameters.
As always, the code samples are available over on GitHub.