Youky Design

menu

Vararg vs. List as Function Arguments in Kotlin

Published on:

When crafting functions in Kotlin, you often need to handle multiple arguments of the same type. While List is a common go-to, Kotlin offers another neat feature: vararg. Let's dive into the differences.

Vararg vs. List as Function Arguments in Kotlinthumbnail

When crafting functions in Kotlin, you often need to handle multiple arguments of the same type. While List is a common go-to, Kotlin offers another neat feature: vararg. Let's dive into the differences.

vararg, short for variable arguments, is used when a function needs many arguments of the same type, and at the time of function creation, the developer doesn’t know exactly how many arguments will be required.

To create a vararg parameter, you add the vararg keyword before the argument’s name.

fun functionName(vararg arguments: Type) {
    // ...
}

For example, consider a function to sum numbers:

fun sum(vararg numbers: Int): Int {
    var total = 0 // Renamed 'sum' to 'total' to avoid conflict with function name
    for (number in numbers) {
        total += number
    }
    return total
}

This function can be called by providing as many Int arguments as needed:

val result1 = sum(1, 2, 3, 4, 5) // Result: 15
val result2 = sum(10, 20, 30)    // Result: 60

You can also pass an existing array using the spread operator (*):

val numbersArray = intArrayOf(1, 2, 3) // Use intArrayOf for primitive int array
val resultFromArray = sum(*numbersArray) // Result: 6

So, if you can use an array, why not just use a List?

Okay, it’s true that both vararg and List offer solutions for handling multiple arguments. However, what about simpler scenarios where the number of arguments isn’t as large as what you might typically store in a List? Again, vararg shines when a function has several arguments of the same type, and you don’t know the exact count beforehand when calling the function.

Let’s look at the sum function defined using both approaches:

// Using vararg
fun sumVararg(vararg numbers: Int): Int {
    var total = 0
    for (number in numbers) {
        total += number
    }
    return total
}

// Using List
fun sumList(numbers: List<Int>): Int {
    var total = 0
    for (number in numbers) {
        total += number
    }
    return total
}

Advantages of vararg

  1. Type Safety at Call Site: Each argument passed to a vararg parameter directly matches the declared type.
  2. Direct Argument Passing: You can pass arguments one by one without manually creating a list or array first.
  3. Array-Like Access: Inside the function, a vararg parameter is treated like an array (Array<out T>), so you can access items by index (e.g., numbers[0]) or iterate over them.
  4. Spread Operator Convenience: You can easily pass an existing array using the spread operator (_).

Advantages of List

  1. Rich API: List (and its mutable counterpart MutableList) comes with a vast collection of powerful extension functions like map, forEach, filter, firstOrNull, add, remove, contains, size, etc., making complex data manipulations easier.
  2. Mutability (Optional): If you use MutableList<T>, you can modify the collection (add, remove, or change items) directly. vararg parameters are read-only arrays within the function.
  3. Flexibility for Existing Collections: If your data is already in a List (or can be easily converted to one), passing it directly can be more straightforward than potentially needing to convert it to an array for a vararg spread.

When to Use vararg

When a function naturally takes a variable number of arguments of the same type that are logically distinct at the call site (e.g., log(message, arg1, arg2, arg3)). When you want the call site to be cleaner for a small, variable number of arguments, without forcing the caller to manually create a list. For functions like String.format or custom builders where arguments are directly supplied.

When to Use List

When you already have your data in a collection or when the data naturally forms a conceptual list. When you need to perform complex operations on the collection of arguments (filtering, mapping, sorting, adding, removing) using the rich List API. When the number of items is typically large, making individual argument passing impractical. When the order or content of items might need to be modified within the function (using MutableList).

Important Rules for vararg:

A function can only have one vararg parameter. If other parameters are present, the vararg parameter must typically be the last one in the parameter list. (Exception: If a function type is the last parameter, vararg can precede it).


To pass an array as a vararg argument, you must use the spread operator (_). Simply put, if you have a few arguments of the same type, vararg can simplify the function call. However, if the function requires significant data manipulation on the arguments, or if you’re already working with a collection, List is often the better choice. The best option depends on the specific needs of your program and what makes your code clearer and more maintainable.