Size: a a a

Kotlin Community

2019 December 12

VB

Viacheslav Blinov in Kotlin Community
ну нет дак нет))
источник
2019 December 13

VB

Viacheslav Blinov in Kotlin Community
в одном пакадже имеется два экстеншн-метода с одинаковыми именами но разными ресиверами, один из которых имеет более широкий тип. Компилятор и IDE путаются в показаниях, какой из них используется на месте вызова.
Понимаю, что это странная практика, но меня сейчас интересует скорее другой вопрос - возможно ли чисто с языковой  точки зрения уточнить какой из них использовать
источник

VB

Viacheslav Blinov in Kotlin Community
гипотетический пример
interface Foo{}
fun Any.toFoo(): Foo //1
fun List<Any>.toFoo(): List<Foo> // 2
....
listOf().toFoo() // IDE says it's 2, compiler says it's 1
источник

VB

Viacheslav Blinov in Kotlin Community
просьба варианты типа использовать разные пакаджи/компаньон/разные имена методов не предлагать. Меня чисто с точки зрения дизайна языка интересует, есть ли решение :)
источник

AL

Alexander Levin in Kotlin Community
Viacheslav Blinov
гипотетический пример
interface Foo{}
fun Any.toFoo(): Foo //1
fun List<Any>.toFoo(): List<Foo> // 2
....
listOf().toFoo() // IDE says it's 2, compiler says it's 1
Вообще у меня везде второй вариант выводится, что звучит логично.

Если я правильно помню правила, то статический вывод работает примерно как "матчу с самым конкретным типом, который я распознал". Если это не устраивает - можно сделать тип менее точным:

val forgetType: Any = listOf<Nothing>()
forgetType.toFoo() // 1
источник

OY

Oleg Yukhnevich in Kotlin Community
Viacheslav Blinov
гипотетический пример
interface Foo{}
fun Any.toFoo(): Foo //1
fun List<Any>.toFoo(): List<Foo> // 2
....
listOf().toFoo() // IDE says it's 2, compiler says it's 1
такое происходит потому что New Inference в IDE включён, а в компиляторе нет
и в New Inference listOf() - выведет к List<Any?>
источник

VB

Viacheslav Blinov in Kotlin Community
Alexander Levin
Вообще у меня везде второй вариант выводится, что звучит логично.

Если я правильно помню правила, то статический вывод работает примерно как "матчу с самым конкретным типом, который я распознал". Если это не устраивает - можно сделать тип менее точным:

val forgetType: Any = listOf<Nothing>()
forgetType.toFoo() // 1
да, проблема вобщем-то в том что у меня до недавнего времени везде второй вариант и выводился. Но что-то случилось и проект перестал компилиться без видимых на то причин
источник

OY

Oleg Yukhnevich in Kotlin Community
попробуй сделать fun List<Any?>.toFoo(): List<Foo> // 2
должен вывести ко второму
источник

DB

Dmitry Baynak in Kotlin Community
почему голый listOf() вообще не кидает ошибку компиляции?
источник

AL

Alexander Levin in Kotlin Community
Dmitry Baynak
почему голый listOf() вообще не кидает ошибку компиляции?
У меня кидает (инференс явно не менял), хотя было бы неплохо просто выводить List<Nothing>, что было бы логично.
источник

VB

Viacheslav Blinov in Kotlin Community
Oleg Yukhnevich
попробуй сделать fun List<Any?>.toFoo(): List<Foo> // 2
должен вывести ко второму
не помогло :)
источник

VB

Viacheslav Blinov in Kotlin Community
Dmitry Baynak
почему голый listOf() вообще не кидает ошибку компиляции?
кидает, это косяк примера кода который я побыстрому склепал
источник

OY

Oleg Yukhnevich in Kotlin Community
Viacheslav Blinov
не помогло :)
А может и Nothing:)
источник

DB

Dmitry Baynak in Kotlin Community
так а какой тогда тип выводит listOf() в примере?
источник

VB

Viacheslav Blinov in Kotlin Community
Alexander Levin
Вообще у меня везде второй вариант выводится, что звучит логично.

Если я правильно помню правила, то статический вывод работает примерно как "матчу с самым конкретным типом, который я распознал". Если это не устраивает - можно сделать тип менее точным:

val forgetType: Any = listOf<Nothing>()
forgetType.toFoo() // 1
я подозреваю что это как-то связанно именно с импортом. Оба экстеншна определены в разных файлах хоть и в одном пакадже, а колл-сайт делает импорт
источник

VB

Viacheslav Blinov in Kotlin Community
тупо перенос второго метода в файл где находится его вызов решает проблему
источник

VB

Viacheslav Blinov in Kotlin Community
изолированный код так-же сломать не выходит :(
источник

VB

Viacheslav Blinov in Kotlin Community
это уже второй странный глюк за неделю, который не получается выделить из проекта. В начале недели наблюдал имплементацию интерфейса через делегат с оверрайдом одного метода, в котором оверрайд не вызывался 😕 В итоге решил тупо ручным оверрайдом всех методов интерфейса, а вот изолированно воспроизвести это тоже не вышло
источник

VB

Viacheslav Blinov in Kotlin Community
разобрался. Вобщем это баг идеи)) На самом деле второй экстеншн определен в подпроекте из которого не должен быть виден (и не виден на этапе компиляции) на месте вызова проблемном. Все компилилось до его переноса туда.
А IDE при этом ошибочно считает что эти модули видят друг друга, поэтому там все выводится
источник

VB

Viacheslav Blinov in Kotlin Community
помог бы понять это раньше сломанный импорт, но т.к. есть второй экстеншн с таким именем импорт не сломался, и компилятор стал подставлять его
источник