Member-only story
In and out type variant of Kotlin
If you ever defined generic in Kotlin, you’ll notice many a times, it would propose to use the in
or out
keyword to define the generic. It puzzles me at a start on when which is used, and for what.
Formally, this is a way to define contravariance and covariant. It took me a while to learn about it. I’ll dive in here to explain what how I understand and memorize their different.
In & Out easily remembered
Out (covariant type)
If your generic class only use the generic type as output of it’s function/s, then out
is used i.e.
interface Production<out T> {
fun produce(): T
}
I call it production class/interface, as it is mainly to produce output of the generic type. Hence very simple one could remember
produce = output = out.
In (contravariance type)
If your generic class only use the generic type as input of it’s function/s, then in
is used i.e.
interface Consumer<in T> {
fun consume(item: T)
}
I call it consumer class/interface, as it is mainly consuming the generic type. Hence very simple one could remember
consume = input = in.
Invariant Type
In the event one generic class uses the generic type as input and output to it’s function, then no in
or out
is used. It is invariant.
interface ProductionConsumer<T> {
fun produce(): T
fun consume(item: T)
}
Why use In and Out?
Well, now you could easily remember when in
and out
is stated, what is their significance? Before we go there, let’s define burger class object. It is a fastFood, which is a type of food.
The simple class hierarchy as below.
open class Food
open class FastFood : Food()
class Burger : FastFood()