Kotlin 默认参数排序
Kotlin default parameter ordering
有谁知道为什么调用 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) }
}
}
如果默认参数在没有默认值的参数之前,只能通过调用带有命名参数的函数来使用默认值。
示例:
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
可以将具有默认值的参数放在常规参数(无默认值)之前。但是,您必须牢记以下几点:
- 常规参数的值将是必需的,因此调用者将被迫始终为具有默认参数的参数提供一个值,这使得具有默认参数的目的变得毫无意义。以下将起作用:
x.method1("", 1) { res: Int -> println(res) }
- 如果调用方使用命名参数,则可以跳过默认参数。这就是以下工作的原因:
x.method1(argQ = 1) { res: Int -> println(res) }
将带有默认参数的参数放在尾部位置总是一个好主意,除非最后一个参数代表 lambda 表达式。
有谁知道为什么调用 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) }
}
}
如果默认参数在没有默认值的参数之前,只能通过调用带有命名参数的函数来使用默认值。
示例:
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
可以将具有默认值的参数放在常规参数(无默认值)之前。但是,您必须牢记以下几点:
- 常规参数的值将是必需的,因此调用者将被迫始终为具有默认参数的参数提供一个值,这使得具有默认参数的目的变得毫无意义。以下将起作用:
x.method1("", 1) { res: Int -> println(res) }
- 如果调用方使用命名参数,则可以跳过默认参数。这就是以下工作的原因:
x.method1(argQ = 1) { res: Int -> println(res) }
将带有默认参数的参数放在尾部位置总是一个好主意,除非最后一个参数代表 lambda 表达式。