我听不懂,在kotlin中找不到out关键字的含义。
您可以在此处查看示例:
List<out T>
如果有人可以解释这个意思。我们将不胜感激。
我听不懂,在kotlin中找不到out关键字的含义。
您可以在此处查看示例:
List<out T>
如果有人可以解释这个意思。我们将不胜感激。
Answers:
带有此签名:
List<out T>
你可以这样做:
val doubleList: List<Double> = listOf(1.0, 2.0)
val numberList: List<Number> = doubleList
这意味着T是协变的:
当声明了类C的类型参数T时,C <Base>可以安全地为C <Derived>的超类型。
与in形成对比,例如
Comparable<in T>
你可以这样做:
fun foo(numberComparable: Comparable<Number>) {
val doubleComparable: Comparable<Double> = numberComparable
// ...
}
这意味着T是协变的:
当类型参数Ť一类Ç被声明在,ç<派生>可以安全地是一个超型的ç<数据库>。
记住它的另一种方式:
消费者进入,生产者退出。
-----------------于2019年1月4日更新-----------------
对于“ Consumer in,Producer out ”,我们仅从Producer-call方法读取以获取类型T的结果。并且只能通过传入T类型的参数来写入Consumer-call方法。
在的示例中List<out T>
,很明显,我们可以执行以下操作:
val n1: Number = numberList[0]
val n2: Number = doubleList[0]
因此它是安全的提供List<Double>
时List<Number>
的预期,因而List<Number>
是超类型的List<Double>
,而不是相反。
在以下示例中Comparable<in T>
:
val double: Double = 1.0
doubleComparable.compareTo(double)
numberComparable.compareTo(double)
因此它是安全的提供Comparable<Number>
时Comparable<Double>
的预期,因而Comparable<Double>
是超类型的Comparable<Number>
,而不是相反。
out
部分并不是使List
不可变的部分。您可以轻松地创建List<out T>
具有clear()
方法的自己的接口,因为它不需要任何参数。
List<out T> is like List<? extends T> in Java
和
List<in T> is like List<? super T> in Java
例如,在Kotlin中,您可以执行以下操作
val value : List<Any> = listOf(1,2,3)
//since List signature is List<out T> in Kotlin
List<out T>
表示您可以执行,val list: List<Number> = listOf<Int>()
因为Int
是的派生类型Number
。等效的Java是List<? extends Number> list = new ArrayList<Integer>();
请参阅Kotlin的手册
Kotlin
List<out T>
类型是提供只读操作(如大小,获取等)的接口。像Java中一样,它继承自Collection<T>
,而继承自Iterable<T>
。MutableList<T>
界面会添加更改列表的方法。此模式也适用于Set<out T>/MutableSet<T>
和Map<K, out
V>/MutableMap<K, V>
和这个,
在Kotlin中,有一种方法可以向编译器解释这种情况。这称为声明位置方差:我们可以注释Source的类型参数T,以确保仅从(的)成员返回(产生)它
Source<T>
,而从不使用它。为此,我们提供out修饰符:
> abstract class Source<out T> { > abstract fun nextT(): T } > > fun demo(strs: Source<String>) { > val objects: Source<Any> = strs // This is OK, since T is an out-parameter > // ... }
一般规则是:当声明
T
一个类的类型参数C
时,它只能出现在成员中的外位置C
,但C<Base>
可以安全地返回的超类型C<Derived>
。在“灵巧的词”中,他们说类别
C
在参数中是协变的T
,或者T
是协变类型参数。您可以将C视为T的生产者,而不是T的消费者T
。out修饰符称为方差注释,由于它是在类型参数声明站点提供的,因此我们讨论声明站点方差。这与Java的使用站点差异相反,在Java中,使用类型中的通配符使类型成为协变。
List<out T>
可见的声明来说,最重要的一点 是out
使它不可变(与可变集合相比,后者没有)。在回答中可能需要提及并强调这一点。隐式强制转换是此结果而不是要点的结果(因为不能写List <Number>,因此可以安全地将其作为List <Double>的引用)。