参数和 return 类型函数的 Kotlin 泛型

Kotlin generics for functions in parameter and return type

大家好! 我有一些 class 来自 Java 依赖:

public class MyClass {
   public MyClass copy() {
      ....
   }
   public void init() {
      ...
   }
}

我想在我的 Kotlin 中写一个函数 class:

fun <T : MyClass> prepareListCopy(objects: List<T>?): List<T>? =
        objects?.map { it.copy().apply { init() } }

我希望我的函数接受 return MyClass 的子类型列表,但是 IDE 向我显示此错误: 将 return 类型的封闭函数 'KOtlinClass.prepareListCopy' 更改为 'List< MyClass >?'

如何在此函数中正确定义泛型?

在您提供的定义中,MyClass.copy() returns MyClass。所以即使你有一个子类型(比如MySubClass)并且你调用MySubClass.copy()你仍然会得到一个MyClass,而不是MySubClass

这就是为什么你不能说你的通用函数 returns a List<T>?,你必须说它 returns List<MyClass>?:

fun <T : MyClass> prepareListCopy(objects: List<T>?): List<MyClass>? =
        objects?.map { it.copy().apply { init() } }

(这正是错误消息告诉您的内容 :D)

现在考虑到这个函数的作用,知道确切的 T 已经没有实际意义了,你可以只接受 List<MyClass>List 在其类型参数中是协变的在 Kotlin 中),并且该函数不需要是通用的:

fun prepareListCopy(objects: List<MyClass>?): List<MyClass>? =
        objects?.map { it.copy().apply { init() } }

如果 MyClass 的所有子类的所有实现都保证 copy() returns 与当前实例具有相同的子类型(并且如果 copy() 的文档通过contract),那么你也可以使你的扩展具体化并添加一个安全转换:

inline fun <reified T : MyClass> prepareListCopy(objects: List<T>?): List<T>? =
        objects?.map { it.copy().apply { init() } as T }