Kotlin默认参数排序

时间:2019-06-24 09:42:38

标签: kotlin default-parameters

有人知道为什么对method1的调用不能编译而对method2的调用可以编译吗?

class MyApp {

    interface X {

        fun <Q : Any, A : Any> method1(argStr: String = "", argQ: Q, argH: (A) -> Unit)

        fun <Q : Any, A : Any> method2(argQ: Q, argStr: String = "", argH: (A) -> Unit)
    }

    fun test(x: X) {

        /* Call to method1 does not work - the following errors are produced
         * Error: Kotlin: Type inference failed:
         * fun <Q : Any, A : Any> method1(argStr: String = ..., argQ: Q, argH: (A) -> Unit): Unit
         * cannot be applied to (Int,(Int) -> Unit)
         * Error: Kotlin: The integer literal does not conform to the expected type String
         * Error: Kotlin: No value passed for parameter 'argQ'
         */

        x.method1(1) { res: Int -> println(res) }

        /* No errors here */
        x.method2(1) { res: Int -> println(res) }
    }

}

2 个答案:

答案 0 :(得分:2)

如果默认参数在没有默认值的参数之前,则只能通过调用带有命名参数的函数来使用默认值

示例:

fun foo(bar: Int = 0, baz: Int) { ... }

foo(baz = 1) // The default value bar = 0 is used

在您的示例中,它将起作用:

x.method1(argQ = 1) { res: Int -> println(res) } // The default value argStr = "" is used

Further reading

答案 1 :(得分:0)

可以将具有默认值的参数放在常规参数之前(无默认值)。但是,您必须牢记以下几点:

  1. 将需要常规参数的值,因此将强制调用方始终为具有默认参数的参数提供值,这使得具有默认参数的目的变得毫无意义。以下将起作用:
x.method1("", 1) { res: Int -> println(res) }
  1. 如果调用者使用命名参数,则他们可以跳过默认参数。这是以下原因起作用的原因:
x.method1(argQ = 1) { res: Int -> println(res) }

除非最后一个参数代表lambda表达式,否则最好将带有默认参数的参数放在尾随位置。