Kotlin投影冗余

在阅读关于Kotlin的genericstypes变化和投影时,我想出了一个完全陌生的概念。 有人可以解释一下作者想要解释的想法是什么? 请参阅Kotlin在行动中的引用,MEAP

没有意义得到一个已经out差异的types参数的out ,例如List 。 这意味着与List相同,因为List被声明为class List 。 Kotlin编译器会警告这样的预测是多余的。

这里有两个具体的问题:

  1. 为什么你需要添加投影已经超出投影types列表?
  2. 即使你这样做,你如何得到相同的列表?

如引用,这将是“多余的”,因此你永远不会想这样做。 它根本不增加任何好处。 整个报价与使用地点差异相关 ,即客户指定的差异(对应于Java中的通配符)。 类List已经有一个声明站点variables修饰符out ,这使得use-site应用程序变得冗余。

以下是冗余客户端站点差异的示例:

 fun  useList(list: List) { println("first element: ${list[0]}") } 

我将out修饰符应用于Listtypes的函数参数,这是使用站点方差的一个示例。 编译器注意到"Projection is redundant" 。 这并没有使情况变得更糟,也没有任何改善。

另一方面,如果你使用的是一个没有在声明网站上投影types ,那么它是有道理的。 例如, Array类的方差不受限制: public class Array

重写前面的例子来使用Array ,突然有意义的是添加一个out修饰符,因为这个参数只被用作T的生产者,即不在位置上。

有意义的客户站点变化示例:

 fun  useArray(arr: Array) { println("first element: ${arr[0]}") } 

经验法则

作为一个经验法则,对应于Java的PECS (Producer extends ,Consumer super ),您可以记住Kotlin的POCI (Producer out ,Consumer in )。

  1. 为什么你需要添加投影已经超出投影types列表?

你不这样做,但它可能是偶然发生的,比如通过重构,或者在深层调用链中,你忽略了被传递的generics参数。

  1. 即使你这样做,你如何得到相同的列表?

在一个比喻中,你可以把投影看作是一个幂等变换: out out T和刚才out T相同。