Reputation:
i came to this problem in Kotlin I have a mutable list of type Int which is supposedly to be only for writing, however, it allows me to read from it
{
val listOfInt: MutableList<in Int> = mutableListOf<Number>(1.3434, 4.432)
println(listOfInt[0])
1.3434
}
although it wont let me just simply create without specifying only for writing
{
val listOfInt: MutableList<Int> = mutableListOf<Number>(1.3434, 4.432)
}
As for contravariance you are not supposed to be able to get any data from it. It is a bug or a feature?
Thanks
Upvotes: 1
Views: 132
Reputation: 59303
Try this:
val list:MutableList<in Int> = mutableListOf(1)
val x:Int = list[0] //Error
The difference is that println
takes an Any?
Given a MutableList<in Int>
, the specified type only applies to things you put into it. They have to be Int
or subclasses. It does not apply to things you get out of it, so they are Any?
. All the methods that read things are still there, though.
The restrictions you're thinking of show up when you declare a class:
class A<in T>
{
fun getIt() : T? = null //Error
}
Here the compiler complains, because I say that I want to return a value of the specified type. My request makes no sense, because anyone who tries to use that method would get an Any?
Upvotes: 0
Reputation: 93834
Contravariance doesn’t prevent you from reading. It only prevents the compiler from knowing anything specific about the type of the retrieved items, so the compiler treats them like Any?
which is always safe and requires no casting. Covariance on the other hand does entirely prevent you from writing to the list because if you don’t know the specific allowed type bound, then nothing is safe to put into the list.
Upvotes: 1