Home > front end >  why is variance having an effect on the flatmapto function?
why is variance having an effect on the flatmapto function?

Time:09-17

I am trying to understand this function:

public inline fun <T, R, C : MutableCollection<in R>> Array<out T>.flatMapTo(destination: C, transform: (T) -> Iterable<R>): C {
    for (element in this) {
         val list = transform(element)
         destination.addAll(list)
     }
     return destination
}

if I swap in with out in MutableCollection<in R>, destination.addAll(list) stops working. The error is that addAll expected nothing. Why doesn't it work? Clearly, list is an Iterable<R>, not an object of type R. For example,

val list = listOf("abc")
list.flatMap{it.toList()}

As I see it, Iterable<R> is a list of "abc" and not "abc" itself. I mean the list of "abc" is not R, but the whole Iterable<R>. then why does out stops the code from working?

CodePudding user response:

Out projected types can not use methods that consume an object of generic type

That is how out projected types work. when you write C : MutableCollection<out R>, this means C is a producer of R's, or in other words C is sub-type of a MutableCollection which can only have methods that produce R and it can not support any methods that consume R or any other generic type with type argument R.

since destination is of type C, you get the error saying Nothing was expected, signifying that consumer methods of this collection are not accessible.

using in makes it a consumer of R's and hence you are able to use addAll, which is a consumer method in R.

  • Related