以下代码可以正常工作,并且对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()
}
错误:类型推断失败:没有足够的信息来内联fun get()来推断参数T:T 请明确指定。
val vm = foo.get() ^
如何将函数移到类中?
答案 0 :(得分:4)
扩展功能返回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)
}
}