Use-site variance applies a variance constraint to one occurrence of a generic type, rather than changing the generic class declaration. Kotlin uses it when a particular parameter is only read from or only written to, and it corresponds to Java wildcards such as ? extends and ? super. section 11.0 section 11.3.5
Copying from a producer
fun <T> copyData(source: MutableList<out T>, destination: MutableList<T>) { for (item in source) { destination.add(item) } } The `out T` projection makes `source` readable as a producer of `T`. The function can therefore copy values from a more specific collection into a destination collection of the chosen type, even though `MutableList` is invariant in general. section 11.3.5
Choose the projection according to how the occurrence is used:
- `MutableList<out T>` permits reading values as `T`, but prevents adding values because the precise element type is unknown. section 11.3.5
- `MutableList<in T>` permits writing `T` values into the destination while hiding the specific supertype used by that collection. section 11.3.5
- A function can instead use two type parameters, such as `<T: R>`, to copy a subtype collection into a supertype collection without projections. section 11.3.5
Listing 11.16 A data copy function with an out-projected type parameter
fun <T> copyData(source: MutableList<out T>, #1
destination: MutableList<T>) {
for (item in source) {
destination.add(item)
}
}
Inspect the compact Kotlin implementation that projects the source list with `out`. section 11.3.5
Declaration-site variance is usually more concise because a class declares its variance once. Use-site variance remains useful when a generally invariant type, such as `MutableList`, has a producer or consumer role at one particular call site. section 11.3.5
