I am trying a code snippet on modifying of an element of an array, and it does seem to work. I get a “Type mismatch” error(squiggly red line) on the line "things[0] = “zero”.
(line before: val things = arrayOf(1,2,3,“one”,“two”,“three”))
According to kotlin help, it should work. What have I done wrong?
Confirmed in the REPL:
>>> val things = arrayOf(1, 2, 3, "one", "two", "three")
>>> things[0] = "zero"
error: type mismatch: inferred type is String but Nothing was expected
things[0] = "zero"
^
(It’s not specific to arrays; you get the same issue with mutableListOf()
.)
The immediate cause is that the inferred type of things
is Array<out Any>
.⠀Because that’s covariant, it could refer to an array of Any
, or of any subtype of Any
.⠀So there’s no value that’s safe to write to it.⠀(The type Nothing
has no values, which is why that’s expected.)
But I must be half-asleep, because I can’t see why it’s inferring an out
type…⠀(It does so even if you specify arrayOf<Any>(…)
!⠀You need to specify things: Array<Any> = …
explicitly to get the invariant type.)
By the way: The reason that Nothing
comes up in such cases is not as arbitrary as one might think. The reason behind it is that Nothing
is defined to be the subtype of every existing type (just like Any
is supertype for everything). Which is a piece of ingenious language design, if you ask me (think about how nicely that plays out for when
branches with the Nothing
type not changing the whole when
expression type, for example). So, because the covariant Any
will walk the inheritance structure upwards, it will eventually land at Nothing
.
Why it assumes covariance in this case, I don’t know. I’ve always had trouble grasping the generic variance concept. I know it’s very logical, but it just does not want to fit into my head…
It seems to infer invariant type in this case.
fun main() {
val things = arrayOf<Any>(1, 2, 3, "one", "two", "three")
things[0] = "zero"
println(things.joinToString())
}
From your items of array, I think you’re trying to practise Kotlin from one of LinkedIn Learning courses. Is that right?