Issue
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?
Solution
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.
Answered By - mightyWOZ
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.