结合println对Kotlin重载解析度的歧义

时间:2018-10-07 00:29:14

标签: kotlin println ambiguity

当引用是对中的第一个元素时,将对println的引用用作对元素失败。

    >>> 0 to ::println

产生

    (0, fun println(): kotlin.Unit)

但是

    >>> ::println to 0

给予

    error: overload resolution ambiguity

在两种情况下,使用Pair()显式定义该对都可以。

这种行为的原因是什么?

1 个答案:

答案 0 :(得分:2)

您可能会发现有趣的事情。

鉴于println有一个不带参数的版本,当您未指定期望的类型::println时,即选择了该版本。 [需要引用:我找不到任何文档/说明表明是这种情况,但这就是在Kotlin 1.2.71中尝试显示的内容]

第二部分是infix funto”是扩展方法,因此需要先解析类型,然后才能调用它。

因此,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

最后,当您只有带有WITH参数的选项时,它会变得有趣:

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?