2017-02-22 77 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