Kotlin vararg and spread operator
vararg lets a function accept any number of arguments of the same type. Instead of passing a fixed count of values, the caller can pass zero, one, or many. Inside the function, those values arrive as an array. The spread operator * does the reverse — it unpacks an existing array into individual arguments.
Defining a vararg Function
fun sum(vararg numbers: Int): Int {
return numbers.sum()
}
fun main() {
println(sum()) // 0
println(sum(5)) // 5
println(sum(1, 2, 3)) // 6
println(sum(10, 20, 30, 40)) // 100
}How vararg Works
fun greetAll(vararg names: String) {
// names is an Array inside the function
for (name in names) {
println("Hello, $name!")
}
}
greetAll("Alice", "Bob", "Carol")
→ names = ["Alice", "Bob", "Carol"]
greetAll()
→ names = [] (empty array)
vararg Position Rules
// vararg must be the last parameter, or other params must use named arguments
fun log(level: String, vararg messages: String) {
messages.forEach { println("[$level] $it") }
}
fun main() {
log("INFO", "App started", "Database connected", "Ready")
log("ERROR", "Connection failed")
}Output:
[INFO] App started
[INFO] Database connected
[INFO] Ready
[ERROR] Connection failedAccessing vararg as Array
fun stats(vararg values: Double) {
println("Count : ${values.size}")
println("Sum : ${values.sum()}")
println("Average: ${"%.2f".format(values.average())}")
println("Min : ${values.min()}")
println("Max : ${values.max()}")
}
fun main() {
stats(12.5, 9.0, 15.0, 7.5, 11.0)
}Output:
Count : 5
Sum : 55.0
Average: 11.00
Min : 7.5
Max : 15.0The Spread Operator *
When you already have an array and want to pass it to a vararg function, use * (the spread operator) to unpack it:
fun printAll(vararg items: String) {
items.forEach { println(it) }
}
fun main() {
val fruits = arrayOf("Apple", "Mango", "Banana")
// Without spread — passes the array as one argument (wrong):
// printAll(fruits) ← type error
// With spread — unpacks array into individual arguments:
printAll(*fruits) // Apple Mango Banana
}Combining Spread with Other Arguments
fun main() {
val extras = arrayOf("Mango", "Grape")
// Mix individual values with a spread array
printAll("Apple", *extras, "Cherry")
// Output: Apple Mango Grape Cherry
}vararg with Generic Types
fun listOf2(vararg elements: T): List = elements.toList()
fun main() {
val names = listOf2("Alice", "Bob", "Carol")
val nums = listOf2(1, 2, 3, 4, 5)
println(names) // [Alice, Bob, Carol]
println(nums) // [1, 2, 3, 4, 5]
} Practical Example: Query Builder
fun buildQuery(table: String, vararg conditions: String): String {
return if (conditions.isEmpty()) {
"SELECT * FROM $table"
} else {
val where = conditions.joinToString(" AND ")
"SELECT * FROM $table WHERE $where"
}
}
fun main() {
println(buildQuery("users"))
println(buildQuery("orders", "status = 'shipped'"))
println(buildQuery("products", "price < 1000", "stock > 0", "category = 'Electronics'"))
}Output:
SELECT * FROM users
SELECT * FROM orders WHERE status = 'shipped'
SELECT * FROM products WHERE price < 1000 AND stock > 0 AND category = 'Electronics'