如何使参数默认?

时间:2017-02-22 08:55:28

标签: kotlin

我发现一个奇怪的默认参数值不是默认值:

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

1 个答案:

答案 0 :(得分: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