2017-02-22 91 views
2

我发现不是默认,默认参数值的奇案:如何使参数默认?

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 
} 

的编译错误:

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 

回答

7

当你拨打电话,以默认参数的函数,你仍然不能隐式跳过它们并传递下面的内容,你只能使用显式的命名参数来做到这一点。

例子:

fun f(x: Int, y: Double = 0.0, z: String) { /*...*/ } 
  • 您可以随时通过x作为非命名参数,因为它被放置在默认参数前:

    f(1, z = "abc") 
    
  • 你可以,当然,按顺序传递所有参数:

    f(1, 1.0, "abc") 
    
  • 但你不能跳过一个默认参数,并通过这些跟随它没有一个明确的标签:

    f(1, "abc") // ERROR 
    f(1, z = "abc") // OK 
    

(demo of this code)

基本上,当你不使用命名参数,参数按照参数的顺序传递,而不会跳过缺省参数。

唯一的例外是在最后一个参数的代码块的语法制成时,它具有的功能类型:

fun g(x: Int = 0, action:() -> Unit) { action() } 

g(0) { println("abc") } 
g { println("abc") } // OK