当前位置: 首页 > 知识库问答 >
问题:

用Kotlin实例化泛型数组

公冶鸣
2023-03-14

为什么这个不能编译?我在3行得到编译错误

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

共有1个答案

和谦
2023-03-14

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

因此,可以实例化数组 数组 ,但不能实例化数组 ,其中t是类型参数,表示在编译时被擦除的类型,因此是未知的。若要指定在编译时必须已知类型参数,请使用reificated修饰符对其进行标记。

在这种情况下,您可以做以下几种选择:

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

使用数组 作为存储,并在get函数中将其值强制转换为t

val data = Array<Any?>(rows * cols, { .... })

operator fun get(row: Int, col: Int): T = data[row * cols + col] as T

class kclass 类型的参数传递给构造函数,并使用java反射创建数组实例。

 类似资料:
  • 主要内容:泛型约束,型变,星号投射泛型,即 "参数化类型",将类型参数化,可以用在类,接口,方法上。 与 Java 一样,Kotlin 也提供泛型,为类型安全提供保证,消除类型强转的烦恼。 声明一个泛型类: 创建类的实例时我们需要指定类型参数: 以下实例向泛型类 Box 传入整型数据和字符串: 输出结果为: 定义泛型类型变量,可以完整地写明类型参数,如果编译器可以自动推定类型参数,也可以省略类型参数。 Kotlin 泛型函数的声明

  • 泛型,即 "参数化类型",将类型参数化,可以用在类,接口,方法上。 与 Java 一样,Kotlin 也提供泛型,为类型安全提供保证,消除类型强转的烦恼。 声明一个泛型类: class Box<T>(t: T) { var value = t } 创建类的实例时我们需要指定类型参数: val box: Box<Int> = Box<Int>(1) // 或者 val box = Bo

  • 问题内容: 我想在Java中创建泛型类型的对象。请提出如何实现相同的建议。 注意:这似乎是一个简单的泛型问题。但是我打赌..不是。:) 假设我的类声明为: 问题答案: 你必须添加异常处理。 你必须在运行时传递实际类型,因为它不是编译后字节码的一部分,因此,没有显式提供它就无法知道它。

  • 问题内容: 我知道Java的泛型在某种程度上逊于.Net。 我有一个泛型类,我确实需要使用无参数构造函数实例化。如何解决Java的局限性? 问题答案: 一种选择是传递(或你感兴趣的任何类型-以任何方式指定适当的引用)并将该值保留为字段: 另一种选择是具有“工厂”接口,然后将工厂传递给泛型类的构造函数。这更加灵活,你无需担心反射异常。

  • 问题内容: 我有这堂课 我正在尝试使用此方法在此类之外创建变量 这给了我这个错误 问题答案: 在实例化泛型时,应将其替换为相应的对象。 例如:

  • 问题内容: 我正在使用泛型编写某些东西,令我惊讶的是,我发现这行不通: 那我不能实例化泛型吗?没有任何方法可以做到这一点吗? 问题答案: 是的,这真是令人讨厌。 我使用的解决方法是强制客户端在构造新类时传递类-即 然后您可以使用。