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.