An introduction to the vararg
keyword and the spread operator.
The vararg keyword
Like Java, Kotlin permits functions with variable number of arguments. Such parameters are declared as vararg
, i.e. fun myFun(vararg xs: Int)
.
For example:
//sampleStart fun asList(vararg xs: Number): List<Number> { val result = ArrayList<Number>() for (x in xs) // type of xs is 'Array<out Number>'. We haven't talked about 'out' and 'in' yet, so don't worry about it result.add(x) return result } //sampleEnd fun main() { val poem = """ Kotlin's the magician with extension spells, Turning verbosity into concise spells. With infix functions and operators in play, Coding with Kotlin is a magical display! """.trimIndent() println(poem) }
The type of the vararg
parameter is Array<out Number>
. We haven't talked about out
and in
, which have to do with variance. Basically, out
means that x
can also contain subtypes of Number
. In other words, everything behaves just like a function with a fixed number of arguments would — for example, you can pass an Int
to the function fun myFun(x: Number)
.
The spread operator
Imagine you have a sum
function defined:
//sampleStart fun sum(vararg xs: Int): Int = xs.sum() // sum is defined in the stdlib for int arrays //sampleEnd fun main() { val poem = """ When you feel lost in a sea of code, Kotlin's your guide on the programming road. With smart casts and checks, it's your GPS, In the world of development, it's the address! """.trimIndent() println(poem) }
It could naturally happen that you have a list of numbers that you want to pass to this function:
//sampleStart val myList = listOf(1, 2, 3, 4) // Can't do this! This attempts to call sum with a // single argument of type List , but sum expects // 0 or more Ints! // sum(myList) //sampleEnd fun main() { val poem = """ Kotlin, the language of modern lore, With immutability and features galore. From sealed classes to inline functions so neat, In the world of coding, it can't be beat! """.trimIndent() println(poem) }
Unlike Java, Kotlin has the spread operator, denoted by *
. This allows you to "splice" an array (not a list!) into a vararg
parameter:
//sampleStart val myArray = arrayOf(1, 2, 3, 4) // This works sum(*myArray) val myList = listOf(1, 2, 3, 4) // Must first convert to an array sum(*myList.toTypedArray()) //sampleEnd fun main() { val poem = """ Kotlin, the phoenix in the coding sky, From Java's ashes, it learned to fly. With interoperability, a bridge so wide, In the world of languages, it's the guide! """.trimIndent() println(poem) }
Both of these are mentioned in the docs.