为什么这不编译?我在3行中得到编译错误
不能使用T作为reified类型参数。使用类
class Matrix2d<T>(val rows: Int, val cols: Int, init: (Int, Int) -> T) {
var data = Array(rows * cols, { i ->
val r = Math.floor(i.toDouble() / cols).toInt()
init(r, i - r * cols)
})
operator fun get(row: Int, col: Int): T = data[row * cols + col]
operator fun set(row: Int, col: Int, v: T) = {
data[row * cols + col] = v
}
}
解决方案
我添加了一个工厂函数,它看起来像第二个构造函数,但是在内联函数中实现
class Matrix2d<T>(val rows: Int, val cols: Int, private val data: Array<T>) {
companion object {
operator inline fun <reified T> invoke(rows: Int, cols: Int, init: (Int, Int) -> T): Matrix2d<T> {
return Matrix2d(rows, cols, Array(rows * cols, { i ->
val r = Math.floor(i.toDouble() / cols).toInt()
init(r, i - r * cols)
}))
}
}
init {
if (rows * cols != data.size) throw IllegalArgumentException("Illegal array size: ${data.size}")
}
operator fun get(row: Int, col: Int): T = data[row * cols + col]
operator fun set(row: Int, col: Int, v: T) {
data[row * cols + col] = v
}
}
答案 0 :(得分:8)
Kotlin数组映射到的JVM数组需要在编译时知道元素类型以创建数组实例。
因此,您可以实例化Array<String>
或Array<Any>
,但不能Array<T>
T
,其中reified
是一个类型参数,表示在编译时被删除的类型,因此未知。
要指定在编译时必须知道类型参数,它将标记为MutableList<T>
修饰符。
有几种选择,在这种情况下你可以做什么:
使用// MutableList function, available in Kotlin 1.1
val data = MutableList(rows * cols, { i ->
val r = i / cols
init(r, i % cols)
})
// or in Kotlin 1.0
val data = mutableListOf<T>().apply {
repeat(rows * cols) { i ->
val r = i / cols
add(init(r, i % cols))
}
}
存储元素,不需要知道T:
inline fun <reified T> Matrix2d(val rows: Int, val cols: Int, init: (Int, Int) -> T) =
Matrix2d(rows, cols, Array(rows * cols, { .... })
class Matrix2d<T>
@PublishedApi internal constructor(
val rows: Int, val cols: Int,
private val data: Array<T>
)
使用带有reified类型参数的内联函数创建数组:
Array<Any?>
使用T
作为存储空间,并将其值转换为get
函数中的val data = Array<Any?>(rows * cols, { .... })
operator fun get(row: Int, col: Int): T = data[row * cols + col] as T
:
Class<T>
将类型KClass<T>
或response.text().then(function (text) {
// do something with the text response
});
的参数传递给构造函数,并使用java反射创建数组实例。
答案 1 :(得分:-1)
就个人而言,对我来说最好的解决方法是:
@Suppress("UNCHECKED_CAST")
var pool: Array<T?> = arrayOfNulls<Any?>(initialCapacity) as Array<T?>