When we invoking a function that has parameters, we can pass arguments by names of these parameters. This approach can improve readability of your code, especially if a function has a lot of parameters. This is also used to change the order of passed arguments in a function call.
Improving code readability
Suppose a cashier sells tickets to a cinema, and within one day the price does not change. It is needed to calculate how much money (amount) will be on the cash desk at the end of the working day. Here is a function that has three parameters:
fun calcEndDayAmount(startAmount: Int, ticketPrice: Int, soldTickets: Int) =
startAmount + ticketPrice * soldTickets
startAmount
is a sum in cash desk before starting this working dayticketPrice
is a today's price of one ticketsoldTickets
is a number of sold tickets on this working day
This is a regular function, let's invoke it as we usually do.
val amount = calcEndDayAmount(1000, 10, 500) // 6000
This works well. But there is one problem - unclear arguments. Of course, we can declare well-named variables and pass them, but sometimes you will work with literals, not variables. To fix this problem, you may name each argument of this function when calling it:
val amount = calcEndDayAmount(startAmount = 1000, ticketPrice = 10, soldTickets = 500) // 6000
Now, this code is easy to understand by humans.
Reordering arguments
Using named arguments, you can change the order of arguments in a function call. Just specify names in any order you need:
val amount = calcEndDayAmount(ticketPrice = 10, soldTickets = 500, startAmount = 1000) // 6000
Mixing named and positional arguments
It is also possible to mix named and regular (positional) arguments in one invocation, as long as all named arguments are placed after all positional arguments.
calcEndDayAmount(1000, ticketPrice = 10, soldTickets = 500) // 6000
The following function invocation is not correct since a named the named argument startAmount
is placed before positional arguments:
calcEndDayAmount(startAmount = 1000, 10, 500) // Incorrect invocation!
Default and named arguments
It is convenient to use named and default arguments together. As you may know, when using default arguments, sometimes Kotlin does not understand which parameters must be assigned.
Let's modify the previous function making the first parameter optional:
fun calcEndDayAmount(startAmount: Int = 0, ticketPrice: Int, soldTickets: Int) =
startAmount + ticketPrice * soldTickets
Suppose, we would like to invoke this function passing only the two last parameters, but it does not work:
val amount = calcEndDayAmount(10, 500) // It does not work: no value passed for soldTickets
Here 10 is assigned to the first optional argument startAmount
, not to the second parameter ticketPrice
.
To invoke this function as you need we must use named parameters:
val amount = calcEndDayAmount(ticketPrice = 10, soldTickets = 500) // 5000
Now it works.