gpt4 book ai didi

generics - Kotlin 中的使用站点差异

转载 作者:行者123 更新时间:2023-12-02 08:04:26 26 4
gpt4 key购买 nike

open class A
class B: A()

fun <T> copy(src: MutableList<T>, dst: MutableList<T>) {
for (i in 0 until src.size) {
dst.add(i, src[i])
}
}

对于上面提到的代码,我理解为 copy function需要类型完全相同的两种类型参数。稍作修改 copy(src: MutableList<T>, dst: MutableList<in T>)注意 in 关键字,我说的是 src 必须是类型 T 但目的地可以是 type TT 的任何父类(super class)型

对于上面修改后的代码,我可以调用如下方法,

fun main(args: Array<String>) {
val l1 = mutableListOf(B(), B())
val l2 = mutableListOf<A>()
copy(l1, l2)
} // main

以上 copy(l1, l2)如果我删除 in 将不起作用 从目的地(理解)。

我的问题是,如果更新函数参数src,我可以毫无错误地调用该函数接受out列表的投影。例如

fun <T> copy(src: MutableList<out /*notice out here*/ T>, dst: MutableList<T>) {
for (i in 0 until src.size) {
dst.add(i, src[i])
}
}

在这种情况下,我无法理解幕后发生的事情。有人可以解释一下吗?

请注意,这只是书中的一个示例。我知道我可以使用 List而不是 src 中的不可变列表

最佳答案

由于您仅以一种方式使用该函数,因此无论如何您都应该使用 use-site variance modifiers 以使调用者清楚您可以添加到 dst并从 src 获取数据:

fun <T> copy(src: MutableList<out T>, dst: MutableList<in T>) {
for (i in 0 until src.size) {
dst.add(i, src[i])
}
}

此外,由于 src确实用作 List而不是 MutableList ,你应该相应地喜欢它。因此,您将不需要 outList 后不再有修饰符已经定义了它的类型参数 T作为out仅:

fun <T> copy(src: List<T>, dst: MutableList<in T>)

针对您的问题:当您调用 copy 时实际会出现问题在你的主列表中有两个不同类型的列表,一次是 MutableList<A>和一次 MutableList<B> .编译器无法推断 copy 的类型是否为应为 AB .要解决此问题,您需要提供更多信息:

1) 当你设置 dst 时至 MutableList<in T> , 编译器知道你只会添加 T基于 src 的类型到它(在你的例子中这是 B )。

2) 当你设置srcMutableList<out T> , 编译器知道你只会添加 T及其子类型为 dst这也很好(在这种情况下,T 将被推断为 A)。

关于generics - Kotlin 中的使用站点差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53151864/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com