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 failed

Accessing 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.0

The 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'

Leave a Comment

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