skip to content

You already have an `Array<String>`. How do you pass it into a function whose parameter is `vararg s: String`? What is the spread operator and what exactly does it do?

level: middleimportance: must knowfreq 65%

answer

  1. before an array = unpack into separate args
  2. Only valid at call site for a vararg param
  3. Spread type must match vararg array type
  4. IntArray spreads into vararg Int (not Array<Int>)
  5. Re-spread to forward varargs onward

basics

~10 s

Put a * before the array when you call the function: printAll(*myArray). The * unpacks the array so each element is passed as a separate argument instead of one array argument.

solid answer

~40 s

Use the **spread operator** `*`: `printAll(*array)`. Without it the compiler would treat `array` as a single argument and complain it is an `Array<String>`, not a `String`. With `*`, each element of the array is forwarded as an individual vararg argument. The spread operator works on the same array type the vararg expects — `Array<out T>` for reference varargs, and the matching primitive array (`IntArray`, etc.) for primitive varargs. It only works at a call site for a `vararg` parameter; you cannot spread into a normal parameter. Spreading creates a copy of the array elements into the underlying varargs array, so callee mutations do not affect your original array's reference contents in a surprising aliased way for the new call frame.

code

kotlin · 5 lines
kotlin
fun greet(vararg names: String) = names.forEach { println("Hi $it") }

val people = arrayOf("Ann", "Bo")
greet(*people)            // Hi Ann / Hi Bo
// greet(people)          // compile error: Array<String> is not String

go deeper

for a junior

Recognizes that *array is needed and that bare array fails to compile.

for a middle

Explains spread unpacks elements, must match the array type, and works only for vararg at call sites.

for a senior

Notes the copy semantics, primitive-array matching, and List→toTypedArray() conversion.

for a principal

Discusses spread's call-site-only nature, ABI implications of varargs forwarding, and avoiding extra array copies in hot paths.

## The problem the spread operator solves Given a `vararg` function and an **existing array**, you cannot just pass the array directly: ```kotlin fun printAll(vararg items: String) = items.forEach(::println) val arr = arrayOf("a", "b", "c") // printAll(arr) // ERROR: expected String, found Array<String> printAll(*arr) // OK — spreads to printAll("a", "b", "c") ``` ## What `*` (spread) does The **spread operator** `*` placed before an array argument **unpacks** that array so each element becomes an individual vararg argument. It is the inverse of collecting values into a vararg. - It is **only** valid at a call site, and **only** for a `vararg` parameter. - The spread expression's type must match the vararg's array type: `Array<out String>` for `vararg s: String`, `IntArray` for `vararg x: Int`, etc. - Spreading **copies** the elements into the new varargs array the callee receives. ## Primitive arrays ```kotlin fun maxOfAll(vararg xs: Int) = xs.max() val data = intArrayOf(3, 1, 2) maxOfAll(*data) // spread an IntArray into vararg Int ``` You must spread an `IntArray` (not `Array<Int>`) into `vararg x: Int`. ## Common use: forwarding varargs When one vararg function delegates to another, you re-spread: ```kotlin fun logAll(vararg msgs: String) = printAll(*msgs) ``` ## Mental model - No `*` → "here is one array argument." - With `*` → "here are N separate arguments taken from this array." The spread is purely a call-site construct; there is no runtime 'spread value' you can store.

  • Can you use `*` on a `List`?
    No. The spread operator works only on arrays (and the matching primitive arrays). Convert with `list.toTypedArray()` first.
  • Can you spread into a non-vararg parameter?
    No. `*` is only valid for an argument bound to a `vararg` parameter.

Like emptying a bag of groceries onto the belt one item at a time instead of putting the whole bag on the belt.

saying these in an interview costs you the question

  • Trying `printAll(arr)` and expecting it to compile
  • Spreading a List directly without toTypedArray()
  • Thinking `*` is multiplication or pointer dereference
  • Spreading an Array<Int> into vararg Int instead of IntArray
  • Believing spread works on any parameter, not just vararg

context