Why is it possible in Kotlin to read from contrvariant list

120 views Asked by At

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

2

There are 2 answers

0
Matt Timmermans On

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?

3
Tenfour04 On

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.