在Kotlin中实例化通用数组

为什么这不编译? 我得到3行的编译错误

不能使用T作为实体类型参数。 改用类

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 } } 

Kotlin数组映射到的JVM数组需要在编译时知道元素类型来创建数组的实例。

所以你可以实例化Array<String>Array<Any> ,而不是Array<T> ,其中T是一个类型参数,代表在编译时被擦除的类型,因此是未知的。 要指定在编译时必须知道类型参数,将使用reified修饰符进行标记。

有几种选择,你可以在这种情况下做什么:

  1. 使用MutableList<T>存储元素,不需要实现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)) } } 
  2. 使用具体化的类型参数从内联函数创建一个数组:

     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> ) 
  3. 使用Array<Any?>作为存储,并在get函数中将其值T

     val data = Array<Any?>(rows * cols, { .... }) operator fun get(row: Int, col: Int): T = data[row * cols + col] as T 
  4. Class<T>KClass<T>类型的参数传递给构造函数,并使用java反射来创建数组的实例。