Recently I ran into a problem where I had a function which had to return an Array of I
s, in form of all values of enum E
, with E
implementing interface I
, with every code that came to my mind compiler complained about type mismatch:
Error:(x, x) Kotlin: Type mismatch: inferred type is Array<E> but Array<I> was expected
A minimal example:
interface I {}
enum class E: I {
A, B, C;
}
fun getMoreInterfaces(): Array<I> {
return E.values()
}
This happens when trying to assign E.values()
to variable of type Array<I>
I am positive that this should be possible since E
implements I
.
Another thing that I came up while testing is that it works just fine when used like this:
interface I {}
enum class E: I {
A, B, C;
}
fun getMoreInterfaces(): Array<I> {
return arrayOf(E.A, E.B, E.C)
}
I did a lot of searching on this topic but with no luck (perhaps I chose the wrong way to describe it?)
In Kotlin, unlike Java, Array<T>
is invariant on T
, so, for E
that is a subtype of I
, Array<E>
and Array<I>
are not subtypes of each other. See: Variance.
Given that the Array<T>
types also store the item type and cannot be subject to fully unchecked casts, your best way to solve this is to create a separate array.
You can do that by either creating an array manually and filling it with the items, like in your example (or by using the constructor Array(n) { ... }
), or use .toTypedArray()
applied to the list representation of the array (.asList()
):
fun getMoreInterfaces(): Array<I> {
return E.values().asList().toTypedArray()
}
But basically, you can just go with a List<I>
if you are not in performance-critical code, which is more idiomatic for Kotlin than working with arrays, and also simpler.