

In summary, in and out are powerful tools in Kotlin, without them, we would have to resort to casting, type checks, and other workarounds to achieve the same level of expressiveness and safety.Welcome to Part 2 of the series on Generics. For example, if we have a List, we can safely access elements of the list as Any, because we know that all the elements of the list are at least of type Any.

Use generic types in function parameters and return types: Using in and out allows us to use generic types in function parameters and return types in a way that preserves subtyping.On the other hand, in allows us to define contravariant generic types, which means that the direction of subtyping is reversed (i.e., a Comparator is a subtype of Comparator). Define covariant and contravariant generic types: out allows us to define covariant generic types, which means that subtyping is preserved (i.e., a List is a subtype of List).Here are a few things that we can do with in and out in Kotlin that would be difficult or impossible without them: This enables us to use more generic types safely and concisely, and it prevents some kinds of type errors that would be possible without it.

With the use of in and out, Kotlin provides support for declaration-site variance, which allows us to define how subtyping works for generic types at the declaration site, rather than at the use site.
