参考 println 的 Pair 中的 Kotlin 重载解析歧义
Kotlin overload resolution ambiguity in Pair with reference to println
当引用是 Pair 中的第一个元素时,使用对 println 的引用作为 Pair 元素失败。
>>> 0 to ::println
生产
(0, fun println(): kotlin.Unit)
但是
>>> ::println to 0
给予
error: overload resolution ambiguity
在这两种情况下,使用 Pair() 显式定义对都可以正常工作。
这种行为的原因是什么?
这里有一些您可能会感兴趣的事情。
鉴于 println
的一个版本不带参数,当您没有指定您希望 ::println
属于的类型时,即选择了该版本。 [需要引用:我找不到任何 documentation/specification 说明是这种情况,但这就是在 Kotlin 1.2.71 中尝试这样做的结果]
第二块是infix fun
“to
”是一个扩展方法,所以在调用它之前需要解析类型。
因此,0 to ::println
会自动被视为 Pair<Int, () -> Unit>
。
要对此进行测试,您可以尝试以下操作:
fun foo(a: Int): Unit = Unit
fun foo(): Unit = Unit
val a = 0 to ::foo // the non-parameter version is selected
val b = ::foo to 0 // there's ambiguity. What extension method "to" to call?
val c: Pair<(Int) -> Unit, Int> = ::foo to 0 // No ambiguity, as I'm specifying the type
现在,如果没有重载:
fun foo(a: Int): Unit = Unit
val a = 0 to ::foo // No ambiguity, there's only one to choose from
val b = ::foo to 0 // Same here, there's only one option
最后,当您只有带有参数的选项时,它会变得有趣:
fun foo(a: Int): Unit = Unit
fun foo(a: Int, b: Int): Unit = Unit
val a = 0 to ::foo // There's no non-parameter version to call, so there's ambiguity
val b = ::foo to 0 // there's ambiguity. What extension method "to" to call?
当引用是 Pair 中的第一个元素时,使用对 println 的引用作为 Pair 元素失败。
>>> 0 to ::println
生产
(0, fun println(): kotlin.Unit)
但是
>>> ::println to 0
给予
error: overload resolution ambiguity
在这两种情况下,使用 Pair() 显式定义对都可以正常工作。
这种行为的原因是什么?
这里有一些您可能会感兴趣的事情。
鉴于 println
的一个版本不带参数,当您没有指定您希望 ::println
属于的类型时,即选择了该版本。 [需要引用:我找不到任何 documentation/specification 说明是这种情况,但这就是在 Kotlin 1.2.71 中尝试这样做的结果]
第二块是infix fun
“to
”是一个扩展方法,所以在调用它之前需要解析类型。
因此,0 to ::println
会自动被视为 Pair<Int, () -> Unit>
。
要对此进行测试,您可以尝试以下操作:
fun foo(a: Int): Unit = Unit
fun foo(): Unit = Unit
val a = 0 to ::foo // the non-parameter version is selected
val b = ::foo to 0 // there's ambiguity. What extension method "to" to call?
val c: Pair<(Int) -> Unit, Int> = ::foo to 0 // No ambiguity, as I'm specifying the type
现在,如果没有重载:
fun foo(a: Int): Unit = Unit
val a = 0 to ::foo // No ambiguity, there's only one to choose from
val b = ::foo to 0 // Same here, there's only one option
最后,当您只有带有参数的选项时,它会变得有趣:
fun foo(a: Int): Unit = Unit
fun foo(a: Int, b: Int): Unit = Unit
val a = 0 to ::foo // There's no non-parameter version to call, so there's ambiguity
val b = ::foo to 0 // there's ambiguity. What extension method "to" to call?