Named arguments
In Kotlin, function arguments can not only be assigned to the corresponding parameters based on their order, but also by name.
While in Java you always have to specify function arguments in the correct order, Kotlin allows you to specify them in any order by referencing them by name.
fun createCustomer(firstName: String, lastName: String, receiveNewsletter: Boolean) : Customer {
// ...
}
createCustomer(lastName = "Example", firstName = "Alex", receiveNewsletter = true)
The biggest advantage is the improved readability.
Even without knowing the signature of createCustomer
, it becomes intuitively accessible when called.
Especially with boolean variables or “magic numbers” it is immediately clear what they do.
So it is obvious that the generated customer should receive the newsletter, while in Java, there would only be a simple true
whose meaning would only become clear by looking at the signature (or with the help of a modern IDE).
Named arguments are particularly useful in conjunction with default arguments.
A prominent example of this is Kotlin’s joinToString
function:
fun <T> Iterable <T>.joinToString(separator: CharSequence = ",", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: (T) -> CharSequence = null) : String
Since every parameter has a meaningful default value here, you can specifically set only those parameters that differ from this default when calling:
strings.joinToString(prefix = "#", separator = ";")
// or, since the order of named parameters does not matter, equivalent:
strings.joinToString(separator = ";", prefix = "#")
This call joins the elements of strings
separated by ;
(instead of ,
) and a prefix #
(instead of none).
All other parameters are set to their default values.
Kotlin offers many other clever applications combining named and default parameters.
Likewise, the automatically generated copy
function of data classes is constructed in such a way that you can simply create copies of an instance and only selectively assign new values to individual properties.
Arguments that are not explicitly specified are simply copied from the source object:
data class Customer(val firstName: String, val lastName: String, val receiveNewsletter: Boolean)
val john = Customer("John", "Doe", true)
// and his sister
val jane = john.copy(firstName="Jane")