Kotlin对象文字实现了野蛮的,自引用的通用接口

时间:2017-03-28 00:03:30

标签: generics kotlin

我有一个接口(在Java中),它接受一个自引用泛型参数,我想在Kotlin中创建一个实现它的对象文字。在Java中,我通过不包括泛型类型(不安全)来做到这一点,但我无法弄清楚如何在Kotlin中做到这一点。

以下是Kotlin中的一个示例,但在我的例子中,界面是Java。

interface Generic<V, T : Generic<V, T>> {
    fun stuff(x: V)
}

class Test {
    // In Java I would write new Generic() { ... }
    val v = object : Generic<*, *> {
        override fun stuff(x: Object) {
            doSomethingThatDoesntCareAboutTypes()
        }
    }
}

我希望能做的是这样,但它不起作用:

val v = object<T : Generic<*, T>> : T {
    override fun stuff(x: Object) {
        doSomethingThatDoesntCareAboutTypes()
    }
}

如何在不必更改界面的情况下执行类似的操作,界面位于不同的模块中且无法轻易更改?

2 个答案:

答案 0 :(得分:3)

星形投影在消费通用接口时特别有用,而在定义实现时很少。 (与Java的?)类似。

为了能够定义实现object的{​​{1}},您需要提供满足约束的类型参数。 Nothing特别是所有Kotlin类型的子类型,因此您可以写:

Generic

答案 1 :(得分:0)

https://kotlinlang.org/docs/reference/generics.html

根据文档,你的例子中的V等不变类型的星形投影解析为。如果T参数不是自引用的,您可以使用:

object : Generic<Any, Any> {}

由于T是自引用的,因此您需要为T引用一个命名类来引用。

class Test {
    val v2 : Generic<*, *>

    init {
        class Impl: Generic<Any, Impl> {
            override fun stuff(x: Any) {
                // ...
            }
        }

        v2 = Impl()
    }
}

另一个可能性是为您创建一个解析自引用泛型的接口。

interface SelfRef<V> : Generic<V, SelfRef<V>>

class Test2 {
    val v = object: SelfRef<Any> {
        override fun stuff(x: Any) {

        }
    }
}