Reputation: 5938
I've found a strange case of the default argument value not being default:
class Dog
class DogHouse(dog: Dog)
inline fun <T: Any, A: Any> build(sth: String = "", call: (A) -> T) {}
fun main(args: Array<String>) {
build(call = ::DogHouse)
build(::DogHouse) // This line fails to compile
}
The compilation error:
Error:(11, 5) Kotlin: Type inference failed: inline fun <T : Any, A : Any> build(sth: String = ..., call: (A) -> T): Unit
cannot be applied to
(KFunction1<@ParameterName Dog, DogHouse>)
Error:(11, 11) Kotlin: Type mismatch: inferred type is KFunction1<@ParameterName Dog, DogHouse> but String was expected
Error:(11, 21) Kotlin: No value passed for parameter call
Upvotes: 2
Views: 226
Reputation: 147911
When you make a call to a function with default arguments, you still cannot skip them implicitly and pass the following ones, you can only use explicit named arguments to do that.
Example:
fun f(x: Int, y: Double = 0.0, z: String) { /*...*/ }
You can always pass x
as non-named argument, because it is placed before the default argument:
f(1, z = "abc")
You can, of course, pass all the arguments in their order:
f(1, 1.0, "abc")
But you cannot skip a default argument and pass those following it without an explicit label:
f(1, "abc") // ERROR
f(1, z = "abc") // OK
Basically, when you don't use named arguments, the arguments are passed in the order of the parameters, without skipping the default arguments.
The only exception is made for the code block syntax of the last argument when it has functional type:
fun g(x: Int = 0, action: () -> Unit) { action() }
g(0) { println("abc") }
g { println("abc") } // OK
Upvotes: 7