具有子类型的 Kotlin 泛型?

Kotlin generics with subtypes?

我无法理解为什么子类型不能与 Kotlin 泛型一起工作。

假设以下简单场景

class Student : Person()
open class Person

这个有效

fun personOrStudent : Person{
return Student()
}

但这不是

fun <Item:Person> personOrStudent() : Item {
return Student()
}

我不明白为什么。 return 类型 Item 不是类型为 Person 的子类型吗? .我相信语法清楚地表明 Item 将是 Person 的子类型。

但是我得到一个编译时错误,说 expected 是 Person ,而不是 student。

这与协变/逆变有关系吗?

通过将函数定义为参数化,我们基本上意味着我们不知道 Item 的确切类型并且它取决于调用站点。 Student 可能是此函数的有效 return 值,但也可能不是。

考虑这个例子:

class NotAStudent : Person()

personOrStudent<NotAStudent>()

我们期望函数 returns NotAStudent,但实现 returned Student。这就是它无法编译的原因。

换句话说:<Item: Person> 并不意味着 Item 只是任何 Person。这意味着 ItemPerson 的一个非常特殊的子类型,但我们不知道是哪一个。

另一种解释方式以防有帮助:

不同之处在于,对于泛型,泛型所代表的类型是在调用它的代码中定义的。您的通用函数没有 return 和 Person。它 return 是调用者要求的任何特定类型。 <T: Person> 表示调用者只能请求 Person 类型或 Persons 的子类型。

open class Person
class Student : Person()
class Teacher: Person()

//...

val teacher = personOrStudent<Teacher>() // The caller is asking for a Teacher.

如果他们要求 Teacher,学生将是无效响应。

在 real-world 应用程序中,我认为没有理由编写这样的泛型函数,其中泛型类型仅用作 return 类型,而不是参数,因为如果它与任何函数输入无关,则无法 determine/use 请求的类型。但是,对于 reified 类型,这是可能的,因为具体化类型本身就是一个输入。