Kotlin неоднозначность разрешения перегрузки в паре со ссылкой на println - PullRequest
0 голосов
/ 07 октября 2018

Использование ссылки на println в качестве элемента Pair не удается, когда ссылка является первой в паре.

    >>> 0 to ::println

производит

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

, но

    >>> ::println to 0

дает

    error: overload resolution ambiguity

Явное определение пары с помощью Pair () прекрасно работает воба случая.

В чем причина такого поведения?

1 Ответ

0 голосов
/ 28 октября 2018

Здесь происходит несколько вещей, которые могут вас заинтересовать.

Учитывая, что есть одна версия println, которая не принимает параметров, если вы не указали ожидаемый тип ::println чтобы быть, это версия, которая выбрана.[цитата нужна: я не смог найти никакой документации / спецификации, в которой говорилось бы, что это так, но именно это и демонстрируется в 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

Наконец, становится интересно, когда у вас есть только параметры 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?
...