open class Animal(val name: String)
class Dog(name: String) : Animal(name)
class Box<T>(private val item: T) {
fun get(): T {
return item
}
}
fun main() {
val dogBox: Box<Dog> = Box(Dog("Buddy"))
val animalBox: Box<Animal> = dogBox // This would NOT compile
}
这是预料之中的,因为泛型是不变的(我们可以通过使用“out”来解决这个问题——允许协变),但如果我们将 main 的方法体改为
val animalBox: Box<Animal> = Box(Dog("Buddy")) // This compiles
我不明白为什么会发生这种情况,也不明白内部是如何处理的。RHS 不是这样吗Box<Dog>
?通用匹配 Animal 吗?
当你调用
Box
构造函数时,会进行类型推断来确定 的类型参数Box
。它最终决定 的类型参数Box
是Animal
,即你正在执行:构造
Box<Animal>
函数采用 的实例Animal
。Dog
可以转换为Animal
,因此完全没有问题。这里的关键思想是类型推断是双向的。从语言规范来看,
类型推断不仅考虑参数
Dog("Buddy")
,还考虑表达式出现的上下文——赋值的右边需要是类型Box<Animal>
。