任意数组的 Kotlin 可变参数数组

Kotlin vararg array of array of any

我有一个方法接受形式的可变参数

fun arrayOfArrays(vararg aoa: Array<Any>) {
}

现在,我很难理解如何调用这个方法,例如

fun callArrayOfArrays() {
    arrayOfArrays(arrayOf(1), arrayOf(1))      // 0) works
    val a = arrayOf(1)
    arrayOfArrays(a, a)                        // 1) type mismatch: inferred type Array, but Array was expected
    val aoa = arrayOf(a)
    arrayOfArrays(aoa)                         // 2) type mismatch: inferred type Array<array>, but Array was expected
    arrayOfArrays(*aoa)                        // 3) type mismatch: inferred type Array<array>, but Array<out array> was expected
    arrayOfArrays(aoa.toList().toTypedArray()) // 4) works
}

更新: 在得到同事的提醒后,我们认为向 arrayOf() 添加类型可以解决我的一些问题,即以下内容现在可以正常工作:

fun callArrayOfArrays() {
    arrayOfArrays(arrayOf(1), arrayOf(1))
    val a = arrayOf<Any>(1)
    arrayOfArrays(a, a)
    val aoa = arrayOf<Array<Any>>(a)
    arrayOfArrays(*aoa)
    arrayOfArrays(aoa.toList().toTypedArray())
    arrayOfArrays(*(aoa.toList().toTypedArray()))
}

我仍然认为前者也应该没问题。我确实渴望对这种行为有一个可以理解的解释。

我很欣赏案例 0 的工作原理,但我无法理解所有其他案例。

对于情况 1,我希望将 arrayOf(1) 分配给变量不会改变语义,但我们就是这样。

对于案例 2,我希望它像我期望的第一个案例一样工作,只是 "Any" 在这里是一个数组。

对于案例 3,我可以看出区别,但我不明白,当然也不知道如何使它起作用。

对于案例 4,我相信这是采用单个数组的可变参数。不过我也传不出去

我认为这与 T 在对 arrayOf<T>(...).

的调用中的推断有关

我的理解是这样的:

在情况 0 中,arrayOfArrays() 期望的参数类型是 Array<Any>,因此它使编译器将 Array<Any> 推断为表达式 arrayOf(1) 的类型。然后编译器检查 1 是 Any 的实例,这是真的(因为 IntAny 的子类型),因此 1 是 arrayOf<Any>() 的有效参数.

但是,在情况 1 中,arrayOf(1) 除了参数 1 之外没有其他类型信息,它是一个 Int,因此表达式作为一个整体被推断为具有类型 Array<Int>,它不是 Array<Any> 的子类型(因为这里泛型类型参数的不变性)。不过,我不得不承认,错误信息不是那么好。

情况 2 也是如此,其中 aoa 的类型是 Array<Array<Int>> 而不是 Array<Any>。同样,错误消息不是很有帮助。

情况 3 实际上与情况 1 相同,其中 aoa 中的每个元素都应为 Array<Any> 类型,但实际为 Array<Int> 类型。如果 ArrayT 中是协变的,它可能会工作,这可能是 "expected Array<out Any>" 的来源,但我真的不完全理解这里的错误消息。

案例 4 与案例 0 相似,因为编译器具有更多本地类型信息(arrayOfArrays() 期望的类型),因此它指导选择 T 的方式在解释 toTypedArray().

的声明时