Suppose I have a generic class and I need a 2D array of generic type T. If I try the following

class Matrix<T>(width: Int, height: Int) {
    val data: Array<Array<T>> = Array(width, arrayOfNulls<T>(height))
}

the compiler will throw an error saying "Cannot use 'T' as reified type parameter. Use a class instead.".

推荐答案

Just because the syntax has moved on a bit, here's my take on it:

class Array2D<T> (val xSize: Int, val ySize: Int, val array: Array<Array<T>>) {

    companion object {

        inline operator fun <reified T> invoke() = Array2D(0, 0, Array(0, { emptyArray<T>() }))

        inline operator fun <reified T> invoke(xWidth: Int, yWidth: Int) =
            Array2D(xWidth, yWidth, Array(xWidth, { arrayOfNulls<T>(yWidth) }))

        inline operator fun <reified T> invoke(xWidth: Int, yWidth: Int, operator: (Int, Int) -> (T)): Array2D<T> {
            val array = Array(xWidth, {
                val x = it
                Array(yWidth, {operator(x, it)})})
            return Array2D(xWidth, yWidth, array)
        }
    }

    operator fun get(x: Int, y: Int): T {
        return array[x][y]
    }

    operator fun set(x: Int, y: Int, t: T) {
        array[x][y] = t
    }

    inline fun forEach(operation: (T) -> Unit) {
        array.forEach { it.forEach { operation.invoke(it) } }
    }

    inline fun forEachIndexed(operation: (x: Int, y: Int, T) -> Unit) {
        array.forEachIndexed { x, p -> p.forEachIndexed { y, t -> operation.invoke(x, y, t) } }
    }
}

This also allows you to create 2d arrays in a similar manner to 1d arrays, e.g. something like

val array2D = Array2D<String>(5, 5) { x, y -> "$x $y" }

并使用索引操作符访问/设置内容:

val xy = array2D[1, 2]

Kotlin相关问答推荐

在Kotlin Jetpack中重用下拉菜单

如何在Jetpack Compose中从领域查询中读取数据?

将文本与文本字段的内容对齐

关键字';在When Kotlin When-语句中

处理合成层次 struct 中的深层按钮以切换视图

如何通过更改现有数据类型来执行Android房间数据库迁移?

如何优雅地声明一个StateFlow?

在 kotlin 中写入 parcer 可空值

Android数据绑定在自定义视图中注入ViewModel

使用 Hilt 注入 CoroutineWorker

ActivityOptions.makeSceneTransitionAnimation 在具有多个视图的 kotlin 中不起作用

将多个 Kotlin 流合并到一个列表中,而无需等待第一个值

如何将命令行参数传递给Gradle Kotlin DSL

Kotlin协程处理错误和实现

Kotlin 扩展函数 - 覆盖现有方法

未找到导入 kotlinx.coroutines.flow.*

Android 与 Kotlin - 如何使用 HttpUrlConnection

TornadoFX 中设置 PrimaryStage 或 Scene 属性的方法

将字符串转换为HashMap的最简单方法

在 Kotlin 中声明 Byte 会出现编译时错误The integer literal does not conform to the expected type Byte