functionkotlinoverloadingvariadic-functionsdefault-value

Is there way to add one more argument to the function(which has var args) with default value without breaking existing calls?


I have a function

fun foo(
    id: String,
    vararg values: Int,
){
  ...    
}

and there are calls like these

fun bar1(){
    foo("id_1")
    foo("id_2", 1)
    foo("id_3", 1, 2, 3)
}

Now I've understood that I need to add one more argument to foo. but I don't want to break existing calls so I tried to add it with default values:

fun foo(
    id: String,
    attributes: Array<String> = arrayOf("a", "b"),
    vararg values: Int,
){
  ...
}

But

foo("id_2", 1)
foo("id_3", 1, 2, 3)

became broken.

Is there way to add one more argument with default value without breaking existing calls ?


Solution

  • Option 1:

    You can, if you move the new parameter to the end:

    fun foo(
        id: String,
        vararg values: Int,
        attributes: Array<String> = arrayOf("a", "b"),
    ) {
        // ...
    }
    

    But it becomes a bit awkward to call:

    fun bar1() {
        foo("id_1")
        foo("id_2", 1)
        foo("id_3", 1, 2, 3)
        foo("id_3", 1, 2, 3, attributes = arrayOf("a", "b"))
    }
    

    You need to specify the parameter name, otherwise the compiler will think the array is still part of the varargs parameter.


    Option 2:

    You can overload the function:

    fun foo(
        id: String,
        vararg values: Int,
    ) {
        foo(id, arrayOf("a", "b"), *values)
    }
    
    fun foo(
        id: String,
        attributes: Array<String>,
        vararg values: Int,
    ) {
        // ...
    }
    

    Then you can call it like this:

    fun bar1() {
        foo("id_1")
        foo("id_2", 1)
        foo("id_3", 1, 2, 3)
        foo("id_3", arrayOf("a", "b"), 1, 2, 3)
    }
    

    This is more elegant at the call site but you have a little overhead at the declaration side.