Стирание типа Котлина - почему функции, отличающиеся только по универсальному типу, могут быть скомпилированы, а функции, отличающиеся только по типу возврата, - нет? - PullRequest
0 голосов
/ 30 августа 2018

Во время работы над ответом из Как работает стирание в Котлине? Я обнаружил некоторые вещи, которые еще не понял, и не нашел источников, почему так происходит. .

Почему следующее не компилируется?

fun bar(foo: List<*>) = ""
fun bar(foo: List<*>) = 2

пока следующее есть?

fun bar(foo: List<String>) = ""
fun bar(foo: List<Int>) = 2

Для меня это становится еще более любопытным, когда добавляется универсальный тип, который даже не используется, то есть следующие компиляции тоже:

fun bar(foo: List<*>) = ""
fun <T> bar(foo: List<*>) = 2 // T isn't even used

Поскольку последний даже не использует T и, как мы знаем, генерики стираются во время выполнения, почему этот работает, а вариант без универсального типа - нет?

В рамках метода байтового кода допускаются только отличающиеся по типу возврата (уже описано в выше связанном ответе ).

Любые намеки, источники и / или ссылки приветствуются.

Добавлен этот вопрос, теперь также на обсуждение. Kotlinlang.org .

1 Ответ

0 голосов
/ 30 августа 2018

Причина, по которой эти функции компилируются или не компилируются, связана с правилами разрешения перегрузки Kotlin. Kotlin не использует ожидаемый тип для разрешения перегрузок, поэтому при вызове этой функции:

 val x = bar(listOf(""))

... компилятор Kotlin не может определить тип, и он не позволяет устранить неоднозначность вызова, указав тип x явно.

Во втором случае нет проблемы разрешения перегрузки, потому что функции имеют разные типы параметров, и нет проблемы конфликта имен JVM, потому что функции имеют разные типы возврата (и, следовательно, разные стертые сигнатуры). Поэтому код компилируется.

...