参数和 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 }
大家好! 我有一些 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 }