Я недавно изучал Kotlin, хотя у меня были вопросы с ковариантным типом.
Пример кода здесь.
У меня Option
и Option2
оба имеют параметр типа T
и расширение run
.
Я мог понять первые два run
в validation()
, поскольку они ведут себя как Java.
Но почему третья строка компилируется? Option<T>
является инвариантом в T
. Мы не можем передать экземпляр Option<C>
туда, где ожидается Option<B>
.
После того, как я добавил ключевое слово out
для T
, теперь все они могут скомпилироваться. Почему?
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>
}