我有一种接受表格的方法
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)分配给一个变量并不会改变语义,但是我们在这里。
对于第二种情况,我认为它的工作方式就像我期望的第一种情况一样,只是这里的“任意”数组。
对于第三种情况,我可以看到不同之处,但我不明白,当然也不知道如何使它工作。
对于第4种情况,我认为这是使用单个数组的vararg。然而,我也不能传播它。
发布于 2019-04-26 16:25:48
我认为这与T在对arrayOf<T>(...)的调用中被推断为什么有关。
我的理解如下:
在案例0中,arrayOfArrays()所期望的param类型是Array<Any>,因此它使编译器推断Array<Any>为表达式arrayOf(1)的类型。然后编译器检查1是Any的一个实例,这是真(因为Int是Any的一个子类型),因此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>。如果Array在T中是协变的,那么它可以工作,这可能就是“预期的Array<out Any>”的来源,但是我真的不完全理解这里的错误信息。
案例4与案例0相似,因为编译器具有更多的本地类型信息(arrayOfArrays()所期望的类型),因此它指导在解释toTypedArray()声明时选择toTypedArray()的方式。
https://stackoverflow.com/questions/55871154
复制相似问题