kotlin 在虚函数中具体化了泛型

Ben*_*Ben 10 generics interface type-erasure kotlin kotlin-reified-type-parameters

在我的具体课程中,我希望有一个具有以下签名的函数。

inline fun <reified T : Comparable<T>> get(key: String): T

但是我想为这个类提取一个接口,这样我就可以交换实现。但是我不知道如何去做,因为我无法将virtual函数标记为inline.

到目前为止我有这个界面:

interface ModuleSettings {

    fun <T : Comparable<T>> get(key: String) : T

}
Run Code Online (Sandbox Code Playgroud)

这个具体的类

class DefaultModuleSettings : ModuleSettings {

    override inline fun <reified T : Comparable<T>> get(key: String): T {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}
Run Code Online (Sandbox Code Playgroud)

但现在编译器抱怨我试图用reified关键字覆盖泛型类型。有什么办法可以实现这种模式吗?

mar*_*ran 12

您不能内联接口函数,但可以将类对象作为参数。DefaultModuleSettings为了仍然获得相同的函数签名,您可以在委托给接口函数的过程中创建内联具体化重载。如果您只有接口类型的引用,则无法调用它。

像这样的东西:

interface ModuleSettings {
    fun <T : Comparable<T>> get(key: String, clazz: KClass<T>) : T
}

class DefaultModuleSettings : ModuleSettings {

    override fun <T : Comparable<T>> get(key: String, clazz: KClass<T>): T {
        TODO("not implemented")
    }

    inline fun <reified T : Comparable<T>> get(key: String): T = get(key, T::class)

}
Run Code Online (Sandbox Code Playgroud)

编辑:

将内联函数作为扩展函数会更好:

inline fun <reified T : Comparable<T>> ModuleSettings.get(key: String): T = get(key, T::class)
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我想在 kotlin 中确实没有其他方法可以做到这一点,所以我将接受这个答案。该死的JVM (2认同)

Ben*_*Ben 8

我通过扩展函数实现了类似的行为:

interface ModuleSettings {

    fun <T : Comparable<T>> get(key: String, type: KClass<T>): T

}

inline operator fun <reified T : Comparable<T>> ModuleSettings.get(key: String) = get(key, T::class)


class DefaultModuleSettings : ModuleSettings {

    override fun <T : Comparable<T>> get(key: String, type: KClass<T>): T {
        TODO("not implemented") 
    }
}
Run Code Online (Sandbox Code Playgroud)

这并不完全是我所期望达到的目标,但它在语义上是有效的。不过我仍然认为这是一个黑客