Kotlin asterisk operator before variable name or Spread Operator in Kotlin
SyntaxKotlinSyntax Problem Overview
I want to know what exactly an asterisk does before a variable name in Kotlin.
I saw this (*args
) in a Spring boot Kotlin example:
@SpringBootApplication
open class Application {
@Bean
open fun init(repository: CustomerRepository) = CommandLineRunner {
repository.save(Customer("Jack", "Bauer"))
repository.save(Customer("Chloe", "O'Brian"))
repository.save(Customer("Kim", "Bauer"))
repository.save(Customer("David", "Palmer"))
repository.save(Customer("Michelle", "Dessler"))
}
}
fun main(args: Array<String>) {
SpringApplication.run(Application::class.java, *args)
}
Syntax Solutions
Solution 1 - Syntax
The *
operator is known as the Spread Operator in Kotlin.
From the Kotlin Reference... > When we call a vararg-function, we can pass arguments one-by-one, e.g. asList(1, 2, 3), or, if we already have an array and want to pass its contents to the function, we use the spread operator (prefix the array with *):
It can be applied to an Array before passing it into a function that accepts varargs
.
For Example...
If you have a function that accepts a varied number of arguments...
fun sumOfNumbers(vararg numbers: Int): Int {
return numbers.sum()
}
Use the spread operator to pass an array's elements as the arguments:
val numbers = intArrayOf(2, 3, 4)
val sum = sumOfNumbers(*numbers)
println(sum) // Prints '9'
Notes:
- The
*
operator is also the multiplication operator (of course). - The operator can only be used when passing arguments to a function. The result of the operation cannot be stored since it yields no value (it is purely syntactic sugar).
- The operator may confuse some C/C++ programmers at first because it looks like a pointer is being de-referenced. It isn't; Kotlin has no notion of pointers.
- The operator can be used in-between other arguments when calling a vararg function. This is demonstrated in the example here.
- The operator is similar to the
apply
function in various functional programming languages.
Solution 2 - Syntax
In addition to the answers that were directly towards "what is this thing!?!", you often have the case where you have a List
and want to pass it to a function that is expecting a vararg
. For this, the conversion is:
someFunc(x, y, *myList.toTypedArray())
Assuming that last parameter of someFunc
is vararg
of the same type as the elements in the list.
Solution 3 - Syntax
As described in the documentation this is a spread operator:
> When we call a vararg-function, we can pass arguments one-by-one, e.g. > asList(1, 2, 3), or, if we already have an array and want to pass its > contents to the function, we use the spread operator (prefix the array > with *): > > val a = arrayOf(1, 2, 3) > val list = asList(-1, 0, *a, 4)
Solution 4 - Syntax
In Java you can pass an array as is but an advantage of unpacking an array with spread operator *
is that spread operator lets you combine the values from an array and some fixed values in a single call. Java doesn't support this.
Solution 5 - Syntax
If a function which accept a vararg(Variable number of arguments) parameter like:
fun sum(vararg data:Int)
{
// function body here
}
Now to call this method, we can do:
sum(1,2,3,4,5)
But what if we have these value in an array, like:
val array= intArrayOf(1,2,3,4,5)
then, to call this method we have to use spread operator, like:
sum(*array)
Here, *(spread operator) will pass all content of that array.
> *array is equivalent to 1,2,3,4,5
But wait a minute, what if we call it like this: sum(array)
it will give us Type Mismatch compile time error:
> Type mismatch. > Required:Int > Found:IntArray
The problem is sum
function accept a vararg Int
parameter(which accept value like: 1,2,3,4,5) and if we pass array, it will be passed as IntArray
.