0
0
Kotlinprogramming~15 mins

Vararg parameters in Kotlin - Deep Dive

Choose your learning style9 modes available
Overview - Vararg parameters
What is it?
Vararg parameters in Kotlin allow a function to accept zero or more arguments of the same type. Instead of passing a fixed number of values, you can pass any number of values, and the function treats them as an array. This makes functions more flexible and easier to use when the exact number of inputs is unknown. It is declared using the keyword 'vararg' before the parameter type.
Why it matters
Without vararg parameters, you would need to overload functions or pass arrays explicitly every time you want to handle multiple inputs. This would make code longer, harder to read, and less flexible. Varargs simplify calling functions with many arguments and improve code clarity, making programming faster and less error-prone.
Where it fits
Before learning vararg parameters, you should understand basic function declarations and arrays in Kotlin. After mastering varargs, you can explore advanced topics like spread operators, default parameters, and function overloading to write more expressive and reusable code.
Mental Model
Core Idea
Vararg parameters let a function accept any number of arguments as if they were a single list inside the function.
Think of it like...
Imagine a mailbox that can hold any number of letters instead of just one. You can drop in one letter or many letters, and the mailbox treats them all as a collection to deliver.
Function with vararg parameter:

fun example(vararg items: String) {
  // items is an array of Strings
}

Call examples:
example("apple")
example("apple", "banana", "cherry")

Inside the function, items looks like:
["apple", "banana", "cherry"]
Build-Up - 7 Steps
1
FoundationBasic function parameters in Kotlin
🤔
Concept: Functions take fixed numbers of parameters with specific types.
In Kotlin, you define a function with parameters like this: fun greet(name: String) { println("Hello, $name!") } You call it by passing exactly one string: greet("Alice") Trying to pass more or fewer arguments causes an error.
Result
Output: Hello, Alice!
Understanding fixed parameters is essential before learning how to accept flexible numbers of arguments.
2
FoundationArrays as function parameters
🤔
Concept: Functions can accept arrays to handle multiple values as one parameter.
You can pass an array to a function to handle many values: fun printAll(items: Array) { for (item in items) { println(item) } } Call it with: printAll(arrayOf("apple", "banana", "cherry"))
Result
Output: apple banana cherry
Arrays let functions process multiple values, but callers must create arrays explicitly, which can be verbose.
3
IntermediateIntroducing vararg parameters
🤔Before reading on: do you think vararg parameters let you pass multiple arguments without creating an array? Commit to your answer.
Concept: Vararg parameters allow passing multiple arguments directly without wrapping them in an array.
Declare a vararg parameter with the keyword 'vararg': fun printAllVararg(vararg items: String) { for (item in items) { println(item) } } Call it like this: printAllVararg("apple", "banana", "cherry") Inside the function, 'items' behaves like an array.
Result
Output: apple banana cherry
Vararg parameters simplify function calls by letting you pass many arguments naturally, improving code readability.
4
IntermediateUsing spread operator with varargs
🤔Before reading on: do you think you can pass an existing array directly to a vararg parameter without any special syntax? Commit to your answer.
Concept: The spread operator (*) lets you pass an existing array to a vararg parameter as individual arguments.
If you have an array: val fruits = arrayOf("apple", "banana", "cherry") You can pass it to a vararg function using *: printAllVararg(*fruits) This spreads the array elements as separate arguments.
Result
Output: apple banana cherry
Knowing the spread operator lets you combine arrays and vararg parameters flexibly without extra copying.
5
IntermediateVararg with other parameters
🤔
Concept: Functions can have vararg parameters along with regular parameters, but vararg must be last or followed by named parameters.
Example: fun mix(message: String, vararg numbers: Int) { println(message) for (num in numbers) { println(num) } } Call: mix("Numbers:", 1, 2, 3) You can also have parameters after vararg if you use named arguments: fun example(vararg items: String, prefix: String) { println(prefix) for (item in items) println(item) } Call: example("a", "b", prefix = "List:")
Result
Output: Numbers: 1 2 3 and List: a b
Understanding parameter order and named arguments helps avoid syntax errors and write flexible functions.
6
AdvancedVararg performance and memory
🤔Before reading on: do you think vararg parameters create a new array every time the function is called? Commit to your answer.
Concept: Each vararg call creates a new array to hold the arguments, which can affect performance in tight loops.
When you call a function with vararg parameters, Kotlin creates a new array to hold the arguments. For example: fun sum(vararg numbers: Int): Int { return numbers.sum() } Calling sum(1, 2, 3) creates an IntArray of size 3 internally. This means frequent calls with many arguments can cause extra memory use and slowdowns.
Result
Understanding this helps optimize code by avoiding varargs in performance-critical paths.
Knowing the cost of array creation with varargs guides better design decisions in performance-sensitive code.
7
ExpertVararg and Java interoperability
🤔Before reading on: do you think Kotlin vararg functions are called the same way from Java? Commit to your answer.
Concept: Kotlin vararg functions compile to Java methods accepting arrays, so Java callers must pass arrays explicitly.
Kotlin code: fun printAll(vararg items: String) { for (item in items) println(item) } From Java, you call: printAll(new String[]{"apple", "banana"}); Java supports varargs, but Kotlin varargs appear as arrays in Java, so Java callers typically pass arrays explicitly. This affects how Kotlin libraries are used from Java and vice versa.
Result
Understanding this prevents confusion and errors when mixing Kotlin and Java codebases.
Knowing the compilation details of varargs helps write interoperable and maintainable multi-language projects.
Under the Hood
At runtime, Kotlin vararg parameters are implemented as arrays. When a function with a vararg parameter is called, Kotlin creates a new array containing all the passed arguments. Inside the function, the vararg parameter is just a normal array. The spread operator (*) tells the compiler to unpack an existing array into individual arguments, which are then collected into a new array again for the vararg parameter.
Why designed this way?
This design balances flexibility and simplicity. Arrays are a natural way to hold multiple values of the same type. Using arrays under the hood avoids complex calling conventions and keeps interoperability with Java straightforward. The spread operator provides a clear syntax to convert arrays to vararg arguments, avoiding ambiguity.
Call site with varargs
  │
  ▼
Compiler creates array from arguments
  │
  ▼
Function receives array as vararg parameter
  │
  ▼
Function processes array elements

Spread operator usage:
Existing array
  │
  ▼
Spread operator (*) unpacks array elements
  │
  ▼
Compiler creates new array for vararg
  │
  ▼
Function receives array
Myth Busters - 4 Common Misconceptions
Quick: Do you think you can pass multiple arrays directly to a vararg parameter without using the spread operator? Commit to yes or no.
Common Belief:You can pass multiple arrays directly to a vararg parameter without any special syntax.
Tap to reveal reality
Reality:You must use the spread operator (*) to pass an existing array to a vararg parameter; otherwise, the array is treated as a single argument.
Why it matters:Without using the spread operator, the function receives an array inside an array, causing unexpected behavior or errors.
Quick: Do you think vararg parameters can be placed anywhere in the parameter list? Commit to yes or no.
Common Belief:Vararg parameters can be declared anywhere among function parameters.
Tap to reveal reality
Reality:Vararg parameters must be the last parameter or followed only by parameters with default values or named arguments.
Why it matters:Placing vararg parameters incorrectly causes compilation errors and confusion about argument passing.
Quick: Do you think vararg parameters avoid creating arrays internally for performance? Commit to yes or no.
Common Belief:Vararg parameters do not create new arrays internally, so they have no performance cost.
Tap to reveal reality
Reality:Each vararg call creates a new array to hold the arguments, which can impact performance if used heavily.
Why it matters:Ignoring this can lead to inefficient code in performance-critical applications.
Quick: Do you think Kotlin vararg functions are called the same way from Java? Commit to yes or no.
Common Belief:Kotlin vararg functions can be called from Java with multiple arguments directly.
Tap to reveal reality
Reality:From Java, Kotlin vararg functions appear as methods accepting arrays, so Java callers must pass arrays explicitly.
Why it matters:Misunderstanding this causes interoperability bugs and confusion when mixing Kotlin and Java code.
Expert Zone
1
Vararg parameters always create a new array on each call, but inline functions can sometimes optimize away this overhead.
2
When combining vararg with default parameters, Kotlin requires careful ordering and named arguments to avoid ambiguity.
3
Using vararg with generic types can cause type erasure issues, requiring explicit type annotations or workarounds.
When NOT to use
Avoid vararg parameters in performance-critical loops where array creation overhead matters; instead, pass arrays or collections directly. Also, do not use vararg when the number of arguments is fixed or when interoperability with Java requires explicit arrays.
Production Patterns
Vararg parameters are commonly used in logging functions, string formatting, and builder patterns where flexible argument counts improve usability. They are also used in DSLs (Domain Specific Languages) in Kotlin to allow natural syntax for lists of elements.
Connections
Spread operator in JavaScript
Similar pattern of unpacking arrays into individual arguments.
Understanding Kotlin's vararg and spread operator helps grasp JavaScript's spread syntax, improving cross-language fluency.
Function overloading
Vararg parameters reduce the need for multiple overloaded functions with different argument counts.
Knowing varargs helps write cleaner APIs by replacing many overloads with a single flexible function.
Variadic functions in C
Vararg parameters are Kotlin's safer, typed version of C's variadic functions.
Comparing Kotlin varargs with C variadic functions highlights how modern languages improve safety and clarity.
Common Pitfalls
#1Passing an array to a vararg parameter without the spread operator.
Wrong approach:fun printAll(vararg items: String) { for (item in items) println(item) } val fruits = arrayOf("apple", "banana") printAll(fruits) // Incorrect: passes array as single argument
Correct approach:printAll(*fruits) // Correct: spreads array elements as arguments
Root cause:Misunderstanding that vararg expects individual arguments, not an array as one argument.
#2Declaring vararg parameter before other parameters without default values.
Wrong approach:fun example(vararg items: Int, prefix: String) { println(prefix) for (item in items) println(item) } example(1, 2, 3, "Numbers") // Compilation error
Correct approach:fun example(vararg items: Int, prefix: String = "List") { println(prefix) for (item in items) println(item) } example(1, 2, 3, prefix = "Numbers") // Correct
Root cause:Not following Kotlin's rule that vararg must be last or followed only by named/default parameters.
#3Assuming vararg parameters have no performance cost.
Wrong approach:fun sum(vararg numbers: Int): Int { return numbers.sum() } // Called millions of times in a loop without concern
Correct approach:fun sum(numbers: IntArray): Int { return numbers.sum() } // Pass array directly to avoid repeated array creation
Root cause:Ignoring that vararg creates a new array on each call, causing unnecessary memory and CPU use.
Key Takeaways
Vararg parameters let Kotlin functions accept any number of arguments as an array, making calls simpler and more flexible.
The spread operator (*) is required to pass existing arrays to vararg parameters, preventing nested arrays.
Vararg parameters must be last or followed only by named/default parameters to avoid syntax errors.
Each vararg call creates a new array, so use varargs carefully in performance-sensitive code.
Kotlin varargs compile to Java arrays, so Java callers must pass arrays explicitly, affecting interoperability.