在阅读关于Kotlin仿制品类型差异和投影的内容时,我想出了一个完全不熟悉的概念。有人可以解释一下作者想要解释的想法是什么?请引用 Kotlin in Action,MEAP :
获得已out
方差的类型参数的out
投影是没有意义的,例如List<out T>
。这意味着与List<T>
相同,因为List
被声明为class List<out T>
。 Kotlin编译器将警告这种预测是多余的。
这里有两个具体问题:
答案 0 :(得分:4)
如上所述,这将是“多余的”,因此你永远不想这样做。它根本不会增加任何好处。整个引用与 use-site variance 相关,即客户端指定的variance (对应于Java中的通配符)。类List<out T>
已经有一个声明 - 网站差异修饰符out
,这会使out
的使用网站应用程序变得多余。
以下是冗余客户端网站差异的示例:
fun <T> useList(list: List<out T>) {
println("first element: ${list[0]}")
}
我将out
修饰符应用于类型List<T>
的函数参数,这是使用站点差异的示例。编译器注意到它是多余的:"Projection is redundant"
。它不会使情况变得更糟或更好。
另一方面,如果你已经使用了未在声明网站上投影的类型,那么它确实有意义。例如,Array
类的方差不受限制:public class Array<T>
。
重写前一个示例以使用Array
,添加out
修饰符突然变得有意义,因为该参数仅用作T
的生成者,即不在{{ 1}}位置。
有意义的客户端站点差异示例:
in
根据经验,对应于Java的 PECS (制作人fun <T> useArray(arr: Array<out T>) {
println("first element: ${arr[0]}")
}
,消费者extends
),您可以记住 POCI < / strong> for Kotlin(制片人super
,消费者out
)。
答案 1 :(得分:2)
- 为什么您需要在已投出的预计类型列表中添加投影?
醇>
你不会,但它可能偶然发生,例如通过重构或在深度调用链中,你忽略了传递的通用参数。
- 即使您这样做,如何获得相同的列表?
醇>
类似地,您可以将投影视为幂等变换:out out T
与out T
相同。