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

10,092

Solution 1

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

Solution 2

Additional note: because of what you experienced, it is generally a best practice to make default arguments the last parameters in the list. Some languages even force this, such as Python (except that Python allows forced named arguments after defaults, since forcong you to call them by name is how you'd get around having parameters after default arguments anyway).

Share:
10,092
hlupico
Author by

hlupico

Updated on July 08, 2022

Comments

  • hlupico
    hlupico almost 2 years

    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
    }
    
  • Jayson Minard
    Jayson Minard over 8 years
    When you have a lot of default arguments you start to use named parameters a lot more and then the order stops mattering as much because you have to start using named arguments anyway to skip over some of the defaulted.
  • Jacob Zimmerman
    Jacob Zimmerman over 8 years
    You don't necessarily want to force the users of your function to have to learn that much more of your api, and sometimes using named arguments ends up cluttering your code. Plus, forcing named arguments means you definitely can't refactor the names if others are using the function. There is a time and place for defaults and named arguments. Generally, it's safer to put the defaults at the end of the list. I know that my mind has an easier time wrapping around defaults at the end of a list, especially if they're used as flags.