如何将来自 Injekt 库的 injectLazy() 委托与泛型一起使用?
How to use injectLazy() delegate from Injekt library with generics?
我有以下 class 层次结构
interface Presenter
abstract class MvpFragment<P: Presenter> : Fragment() {
val presenter by injectLazy<P>() // error: Cannot use 'T' as reified type parameter. Use a class instead.
}
有什么方法可以将 injectLazy
委托与泛型一起使用吗?我可以将 KClass<P>
作为参数传递给 MvpFragment
,但我仍然不知道如何使用它来注入 P
对象。
编译 Java 代码时,通用类型参数被删除。 Kotlin 提供了一个特性,内联函数可以一直保留这个类型信息到程序的 运行 时间。该功能是 injectLazy<T>
函数用来具体化类型参数的功能。
不过在你的例子中,类型参数 P
来自 class,因此 Kotlin 编译器无法具体化它,这意味着它会在编译为 [=20= 时被删除] 字节码。擦除类型参数后,无法再调用 injectLazy<T>
函数,因为类型信息将在 运行 时丢失。这就是编译器给你错误的原因。
您必须将 KClass<P>
对象传递给您的 class 并使用它来注入依赖项,从而手动具体化类型。
我终于找到了一种方法。但我必须先添加两个新功能:
fun <T: Any> typeRef(type: KClass<T>) = object : TypeReference<T> {
override val type = type.java
}
fun <T : Any> injectLazy(type: KClass<T>): Lazy<T> {
return lazy { Injekt.get(forType = typeRef(type)) }
}
现在我可以写了:
abstract class MvpFragment<P : Presenter>(presenterClass: KClass<P>) : Fragment() {
protected val presenter by injectLazy(type = presenterClass)
}
我有以下 class 层次结构
interface Presenter
abstract class MvpFragment<P: Presenter> : Fragment() {
val presenter by injectLazy<P>() // error: Cannot use 'T' as reified type parameter. Use a class instead.
}
有什么方法可以将 injectLazy
委托与泛型一起使用吗?我可以将 KClass<P>
作为参数传递给 MvpFragment
,但我仍然不知道如何使用它来注入 P
对象。
编译 Java 代码时,通用类型参数被删除。 Kotlin 提供了一个特性,内联函数可以一直保留这个类型信息到程序的 运行 时间。该功能是 injectLazy<T>
函数用来具体化类型参数的功能。
不过在你的例子中,类型参数 P
来自 class,因此 Kotlin 编译器无法具体化它,这意味着它会在编译为 [=20= 时被删除] 字节码。擦除类型参数后,无法再调用 injectLazy<T>
函数,因为类型信息将在 运行 时丢失。这就是编译器给你错误的原因。
您必须将 KClass<P>
对象传递给您的 class 并使用它来注入依赖项,从而手动具体化类型。
我终于找到了一种方法。但我必须先添加两个新功能:
fun <T: Any> typeRef(type: KClass<T>) = object : TypeReference<T> {
override val type = type.java
}
fun <T : Any> injectLazy(type: KClass<T>): Lazy<T> {
return lazy { Injekt.get(forType = typeRef(type)) }
}
现在我可以写了:
abstract class MvpFragment<P : Presenter>(presenterClass: KClass<P>) : Fragment() {
protected val presenter by injectLazy(type = presenterClass)
}