As quoted, it would be “redundant”, thus you’d never want to do that. It simply does not add any benefit. The whole quote is related to use-site variance, i.e. variance specified by the client (corresponds to wildcards in Java). The class List<out T>
already has a declaration-site variance modifier out
, which makes the use-site application of out
redundant.
Here's an example of redundant client-site variance:
fun <T> useList(list: List<out T>) {
println("first element: ${list[0]}")
}
I applied the out
modifier to a function parameter of type List<T>
, this is an example of use-site variance. It is redundant which the compiler notices: "Projection is redundant"
. It does not make it worse nor any better.
On the other hand, if you're using a type that is not projected on declaration-site already, it does make sense. For example, the Array
class is not restricted in its variance: public class Array<T>
.
Rewriting the former example to use Array
, it suddenly makes sense to add an out
modifier, since the parameter is only used as a producer of T
, i.e. not in in
position.
Example of meaningful client-site variance:
fun <T> useArray(arr: Array<out T>) {
println("first element: ${arr[0]}")
}
Rule of Thumb
As a rule of thumb, corresponding to Java‘s PECS (Producer extends
, Consumer super
), you can memorize POCI for Kotlin (Producer out
, Consumer in
).