Kotlin: how to make a function call using the first argument's default value and passing a value for the second?

hlupico picture hlupico · Jan 18, 2016 · Viewed 9.8k times · Source

I'd like to know how to call a function with default arguments when you want to specify the value of the second argument. In the simple example below I am showing that the addTwo() takes two arguments. The 'first' argument has a default value but the 'second does not. How would I call this function specifying that I want to use the default value for 'first' with the given value of 2 for 'second'?

Calling addTwo(2) throws an error.

fun main(args: Array<String>) {
    var sum = addTwo(1,2)    // works fine
    var nextSum = addTwo(2)  // ERROR: No value passed for parameter second 
}

fun addTwo(first: Int = 0, second: Int): Int {
    return first + second
}

Answer

Jayson Minard picture Jayson Minard · Jan 18, 2016

This is an error because Kotlin does not know why you omitted a second parameter. The first can be defaulted, but not second. Therefore when you only passed in one argument it was for parameter first. The error message says exactly what the problem is:

no value passed for parameter second

You must call using named arguments for anything after the first defaulted parameter that you want to leave blank. For your case, this would be:

addTwo(second = 2) // first defaulted to 0

Had your defaulted parameters been in the other order, your call would be fine.

fun addTwo(first: Int, second: Int = 0): Int{
    return first + second
}

addTow(2)  // no error, second defaulted to 0

Had your data types been different for the two parameters, you would have seen a different less clear error letting you know the type of the first parameter (Int) was expected, not the type of the second (Date in the following example):

fun something(first: Int = 0, second: Date): Date { ... }

something(Date()) // ERROR: Type mismatch: inferred type is java.util.Date but kotlin.Int was expected

Note: You can run into the same issue with vararg:

Only one parameter may be marked as vararg. If a vararg parameter is not the last one in the list, values for the following parameters can be passed using the named argument syntax