0

These all compile fine:

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

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

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

But this one gives the error below:

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

Error:(22, 16) Kotlin: Type inference failed. Expected type mismatch: inferred type is Array<Array<Int>> but Array<Array<Any>> was expected

Why?

2 Answers 2

3

In your f4() you're using invariance:

Array<Array<Any>>

Array<Any> and Array<Int> are different types, and are not interchangeable.

If you only return the type, you can use covariance:

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

Since Int is subtype of Any

Sign up to request clarification or add additional context in comments.

Comments

1

arrayOf signature:

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

It works on methods that directly return the array because type is inferred from return type. But it cannot do "nested" inference as you imagine.

This becomes much clearer if you break down your return statement:

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

Now there is no reason why arr assignment would be marked as an error would it?

So if you don't want to infer Int, you have to provide returned type of nested array yourself:

return arrayOf(arrayOf<Any>(1))

1 Comment

Nice explanation. One question still: listOf is declared similarly. Why/how does it work there?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.