在 Kotlin 中是否可以有通用的主构造函数?

6
这将起作用:
class Generic<T, R>(thingy: R)
{
    val x = thingy.getX()
}

但是参数R确实不应该是类签名的一部分。它只在构造时有关联。就像泛型方法的类型参数与类的类型参数无关一样。

然而,这样做是行不通的:

class Generic<T>(thingy: R)
{
    val x = thingy.getX()
}

这也不行:
class Generic<T><R>(thingy: R)
{
    val x = thingy.getX()
}

我在文档中没有找到答案。


5
要在泛型类型R上调用getX()方法,它必须实现某个接口。没有边界的泛型类型将不具有getX方法。你可以直接将Generic参数声明为该接口类型:class Generic<T>(thingy: RInterface) { ... } - marstran
2个回答

10

这是不可能直接实现的。

你可以通过使用工厂方法来实现期望的结果:

interface HasX<out V> {
    val x: V
}

class Generic<T>(val x: Int) {
    companion object {
        fun <T, R : HasX<Int>> create(thingy: R) = Generic<T>(thingy.x)
    }
}

val result: Generic<String> = Generic.create(object : HasX<Int> {
    override val x: Int = 12
})

通常工厂方法以小写字母开头(例如mutableList),但您也可以采用不同的方式:
fun <T, X : HasX<Int>> Generic(thingy: X):Generic<T> = Generic(thingy.x)

val result: Generic<String> = Generic(object : HasX<Int> {
    override val x: Int = 12
})

正如@Alexey Romanow所指出的那样,Kotlin stdlib的部分使用了这种方法


你也可以使用 operator invoke - Alexey Romanov
2
标准库还有 public inline fun <T> MutableList(size: Int, init: (index: Int) -> T): MutableList<T> - Alexey Romanov

2

是的,试试这个。

class MyClass<T>(data: T)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接