为什么这种对嵌套数组元素类型的推断失败?

时间:2018-08-05 14:44:48

标签: generics kotlin

这些都可以编译:

fun f1(): Array<Any> {
    return arrayOf(1)
}

fun f2(): Collection<Any> {
    return listOf(1)
}

fun f3(): Collection<Collection<Any>> {
    return listOf(listOf(1))
}

但这是下面的错误:

fun f4(): Array<Array<Any>> {
    return arrayOf(arrayOf(1)) // compilation error here
}
  

错误:(22,16)Kotlin:类型推断失败。预期的类型不匹配:推断的类型为Array >,但预期为Array >

为什么?

2 个答案:

答案 0 :(得分:3)

在您的f4()中,您使用不变性:

Array<Array<Any>>

Array<Any>Array<Int>是不同的类型,并且不能互换。

如果仅返回类型,则可以使用协方差:

fun f4(): Array<Array<out Any>> {
   return arrayOf(arrayOf(1)) // works
}

由于IntAny的子类型

答案 1 :(得分:1)

arrayOf签名:

inline fun <reified T> arrayOf(vararg elements: T): Array<T> (source)

它适用于直接返回数组的方法,因为类型是从返回类型推断出来的。但是它无法像您想象的那样进行“嵌套”推断。

如果您分解返回语句,这将变得更加清楚:

val arr = arrayOf(1)  // this is an Array<Int> of course
return arrayOf(arr)

现在没有理由将arr分配标记为错误吗?

因此,如果您不想推断Int,则必须自己提供嵌套数组的返回类型:

return arrayOf(arrayOf<Any>(1))