不能使用 R 作为具体化类型参数使用 class 代替抽象 class Kotlin
Cannot use R as reified type parameter use a class instead in abstract class Kotlin
我有几个 class 做几乎相同的事情,所以我想创建一个摘要 class 来删除重复。最简单的方法是通过下面的小例子:
我有 classes A 和 B 为:
class A {
fun create(
request: RA,
): ResponseEntity<RA> {
return foo(RA::class)
}
}
class B {
fun create(
request: RB,
): ResponseEntity<RB> {
return foo(RB::class)
}
}
其中 RA 和 RB 都继承自 RX。
我想创建一个摘要 class 来删除这个重复项。所以我尝试了这样的事情:
abstract class C <R: RX> {
fun create(
request: R,
): ResponseEntity<R> {
return foo(getKClass())
}
abstract fun getKClass() : KClass<R>
}
class A : C() {
fun aMethod() {
println("Hello world!")
}
override fun getKClass() : KClass<A> {
return A::class
}
}
class B : C() {
fun bMethod() {
println("Hello world2!")
}
override fun getKClass() : KClass<B> {
return B::class
}
}
这样 Class A 和 Class B 就可以扩展 Class C 并且删除重复项。问题是,由于 Class C 中的 R 是通用的,我得到错误 cannot use R as reified type parameter. Use a class instead.
我尝试了一些事情,例如使 create
函数内联并在 [=33= 中使用具体化类型] C. 还有什么我应该尝试的还是只保留重复?
我刚刚注意到这个用户 () 的回答,所以我尝试在 class A 和 class B 中使用一个函数,返回 KClass然后在摘要中使用那个classC,也无济于事。
谢谢
如您所链接问题的答案所述:
reified
only works when the type information is known at the call site
at compile time, which is not the case here.
If you want to be able to do that, you need to store a Class or KClass
as a property of your class, or indeed to create a virtual method for
obtaining the Class or KClass instance for each derived class.
所以你可以用这样的东西来实现第一个建议(将 Class 或 KClass 存储为 class 的 属性):
abstract class C<R : RX>(private val clazz: KClass<R>) {
fun create(request: R): ResponseEntity<R> {
return foo(clazz)
}
}
class A : C<RA>(RA::class)
class B : C<RB>(RB::class)
如果您更喜欢第二个建议(创建一个虚拟方法来获取 Class 或 KClass),然后将 clazz
构造函数参数替换为受保护的抽象方法或 属性 代替。 (虽然这里的构造函数参数可能是实现相同结果的代码少了一点,并且可以说是更惯用的方法。)
我假设您有 RA
和 RB
以及 A
和 B
。那是对的吗?你上面的两个代码片段我不是很清楚。
我有几个 class 做几乎相同的事情,所以我想创建一个摘要 class 来删除重复。最简单的方法是通过下面的小例子:
我有 classes A 和 B 为:
class A {
fun create(
request: RA,
): ResponseEntity<RA> {
return foo(RA::class)
}
}
class B {
fun create(
request: RB,
): ResponseEntity<RB> {
return foo(RB::class)
}
}
其中 RA 和 RB 都继承自 RX。
我想创建一个摘要 class 来删除这个重复项。所以我尝试了这样的事情:
abstract class C <R: RX> {
fun create(
request: R,
): ResponseEntity<R> {
return foo(getKClass())
}
abstract fun getKClass() : KClass<R>
}
class A : C() {
fun aMethod() {
println("Hello world!")
}
override fun getKClass() : KClass<A> {
return A::class
}
}
class B : C() {
fun bMethod() {
println("Hello world2!")
}
override fun getKClass() : KClass<B> {
return B::class
}
}
这样 Class A 和 Class B 就可以扩展 Class C 并且删除重复项。问题是,由于 Class C 中的 R 是通用的,我得到错误 cannot use R as reified type parameter. Use a class instead.
我尝试了一些事情,例如使 create
函数内联并在 [=33= 中使用具体化类型] C. 还有什么我应该尝试的还是只保留重复?
我刚刚注意到这个用户 (
谢谢
如您所链接问题的答案所述:
reified
only works when the type information is known at the call site at compile time, which is not the case here.If you want to be able to do that, you need to store a Class or KClass as a property of your class, or indeed to create a virtual method for obtaining the Class or KClass instance for each derived class.
所以你可以用这样的东西来实现第一个建议(将 Class 或 KClass 存储为 class 的 属性):
abstract class C<R : RX>(private val clazz: KClass<R>) {
fun create(request: R): ResponseEntity<R> {
return foo(clazz)
}
}
class A : C<RA>(RA::class)
class B : C<RB>(RB::class)
如果您更喜欢第二个建议(创建一个虚拟方法来获取 Class 或 KClass),然后将 clazz
构造函数参数替换为受保护的抽象方法或 属性 代替。 (虽然这里的构造函数参数可能是实现相同结果的代码少了一点,并且可以说是更惯用的方法。)
我假设您有 RA
和 RB
以及 A
和 B
。那是对的吗?你上面的两个代码片段我不是很清楚。