我最近一直在学习 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>
}