Varargs and spread


Maybe you have used some kind of vararg functionality in another programming language and want to know how it works in Kotlin or maybe the concept is entirely new to you and you just want to know what it is and how it works. In both cases: keep on reading as we’re going to explore the two concepts individually and how they work together. Let’s dive in!

The vararg keyword

The vararg keyword in a function definition basically turns the affected parameter into an Array<out T> in the case of non-primitives. When used on a primitive it will use the most specific type it can, for example IntArray or CharArray.

Basic usage of the vararg keyword:

fun sum(vararg numbers: Int) = numbers.sum() // numbers is of type IntArray
println(sum(1, 2, 3)) // 6

You can also use non-primitives:

data class Person(val name: String)
fun names(vararg people: Person) = people.joinToString { person -> person.name }

Restrictions on vararg usage

It is important to note that there can only be one vararg parameter in a function definition.
Typically you would want to have your vararg parameter als the last one in the argument list, or the semi-last if the last argument is a function type.

Good example

fun test(name: String, vararg numbers: Int, callback: () -> Unit)
test("Hello", 1, 2, 3) {
    println("Executed the callback")
}

Bad example

fun test(vararg numbers: Int, name: String)
test(1, 2, 3, "Dennis") // Typemismatch: expected Int, got String

// Fix it with a named parameter:
fun(1, 2, 3, name = "Dennis")

The spread operator (*)

The spread operator is basically the reverse of vararg. Where vararg turns a list of arguments into an array, spread turns an array into a list of arguments. The same conversion counts as for vararg: you can spread Array<out T> for non-primitives, or IntArray for example when Int arguments are required.

Spread example:

fun sum(vararg numbers: Int) = numbers.sum()

val numbers = intArrayOf(1, 2, 3)
sum(*numbers)

The cool thing is you can even combine multiple spreads:

val numbers = intArrayOf(1, 2, 3)
val morenumbers = intArrayOf(4, 5, 6)

sum(*numbers, *morenumbers)

Conclusion

In this post you have learned what the vararg and spread concepts mean within Kotlin and how to use them.

Happy coding!


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.