如何创建一个在Kotlin中填充空值的通用数组?

我试过这个,代码没有编译。

class GenericClass<T>() { private var arr : Array<T>? = null { arr = Array<T>(10, { null }) } } 

这个代码中报告了两个编译器错误:一个是可空类型,另一个是泛型​​。

可空类型 。 Kotlin强制使用可空引用的规则,并且由于T可以用例如使arr为Array类型的String实例化,因此编译器不允许将空值放入此数组中。 如果你想要null,你必须改变类型为Array:

 class GenericClass<T>() { private var arr : Array<T?>? = null { arr = Array(10, { null }) // No need to specify type arguments again } } 

泛型 。 上面的例子仍然有一个编译时错误,因为我们试图构造一个未知类型的数组T. 注意这个问题也存在于Java中。 被编译为JVM字节码的Kotlin需要两件事情:

  • 泛型类型参数在运行时被擦除,
  • 除了数组的通用参数。

这意味着在字节码中Kotlin必须创建一个具体类型的数组,而不是一个未知的类型T.它可以创建对象的数组,每当它看到数组,但是这不起作用,例如在这种情况下:

 fun test() { fun foo(srts: Array<String?>) { // ... } val gc = GenericClass<String>() foo(gc.arr) } 

在这里,在最后一行,我们正在尝试传递Object [],其中String []是期望的,并且得到一个运行时错误。

这就是为什么Kotlin拒绝创建T的数组。你可以通过明确地禁止类型系统,即通过使用类型转换来解决这个问题:

 class GenericClass<T>() { val arr : Array<T?> { arr = Array<Any?>(10, { null }) as Array<T?> } } 

这里我们明确地要求创建一个Any(编译成Object [])的数组,然后将其转换为T的数组。编译器发出警告,但是服从我们的意愿。

请注意,上面有问题的例子仍然存在,也就是说,如果您希望传递以这种方式创建的数组的字符串,那么在运行时就会失败。

方法

 val array : Array<T?> = kotlin.arrayOfNulls<T>(size) 

从文档

 /** *Returns an array of objects of the given type with the given [size], *initialized with null values. */ public fun <reified @PureReifiable T> arrayOfNulls(size: Int): Array<T?>