I've been recently learning Kotlin, while having some questions with covariant type.
The sample code is here.
I have Option
and Option2
both having a type parameter T
and a run
extension.
I could understand the first two run
in validation()
, since they are behaved as Java.
But why does the third line compile? Option<T>
is invariant in T
. We cannot passing Option<C>
instance into where Option<B>
is expected.
After I add an out
keyword for T
, now all of them could compile. Why?
open class A
open class B : A()
open class C : B()
class Option<T>(val item: T)
fun <T> Option<T>.run(func: (Int) -> Option<T>): Option<T> = func(1)
class Option1<out T>(val item: T) //out keyword
fun <T> Option1<T>.run(func: (Int) -> Option1<T>): Option1<T> = func(1)
fun validation() {
val opt: Option<B> = Option(B())
opt.run { Option(A()) } //won't compile as expected
opt.run { Option(B()) } //return type is Option<B>
opt.run { Option(C()) } //return type is Option<B>; why could this compile?
val opt1: Option1<B> = Option1(B())
opt1.run { Option1(A()) } //return type is Option<A>; why could this compile?
opt1.run { Option1(B()) } //return type is Option<B>
opt1.run { Option1(C()) } //return type is Option<B>
}