Вывод типа работает только для функции расширения - PullRequest
1 голос
/ 29 октября 2019

Следующий код работает нормально, и вызов функции расширения foo.get() возвращает правильный тип BarImpl.

open class Bar
class BarImpl: Bar()

class Foo<T : Bar> 

inline fun <reified T : Bar> Foo<T>.get(): T {
    return SomeMap(this).get(T::class)
}

class Activity {
    lateinit var foo: Foo<BarImpl>
    val barImpl = foo.get()
}

Но когда я пытаюсь переместить Foo<T>.get() в класс, вывод типа завершается неудачно

class Foo<T : Bar> {
    inline fun <reified T : Bar> get(): T {
        return SomeMap(this).get(T::class)
    }
}

class Activity {
    lateinit var foo: Foo<BarImpl>
    val barImpl = foo.get()
}

ошибка: вывод типа не выполнен: недостаточно информации для вывода параметра T во встроенном потоке get (): T Укажите это явно.

   val vm = foo.get()
                ^

Какя могу переместить функцию в класс?

1 Ответ

4 голосов
/ 29 октября 2019

Функция расширения возвращает результат параметра типа Foo. Таким образом, тип результата может быть выведен из типа получателя.

И тип результата функции-члена не имеет ничего общего с параметром типа Foo, кроме имени, что ничего не значит для компилятора. Вы можете увидеть, что T в методе и T в классе - это разные типы, написав и скомпилировав следующий код:

Foo<BarImpl>().get<BarImpl2>()

Если вы хотите сделать get функцией-членом, которая возвращаетВ результате Foo параметра типа вы должны удалить параметр типа из функции и внедрить экземпляр класса через конструктор:

class Foo<T : Bar>(private val clazz: KClass<T>) {
    fun get(): T {
        return SomeMap(this).get(clazz)
    }

    companion object {
        inline operator fun <reified T : Bar> invoke() = Foo(T::class)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...