No soy capaz de entender y no pude encontrar el significado de salir palabra clave en Kotlin.
Puede consultar el ejemplo aquí:
List<out T>
Si alguien puede explicar el significado de esto. Esto sera realmente apreciado.
Con esta firma:
List<out T>
Puedes hacerlo:
val doubleList: List<Double> = listOf(1.0, 2.0)
val numberList: List<Number> = doubleList
lo que significa que T es covariante :
cuando un tipo de parámetro T de una clase C se declara a cabo , C <Base> puede ser de forma segura un supertipo de C <Derivado> .
Esto es contraste con en , por ejemplo,
Comparable<in T>
Puedes hacerlo:
fun foo(numberComparable: Comparable<Number>) {
val doubleComparable: Comparable<Double> = numberComparable
// ...
}
lo que significa que T es contravariante :
cuando un tipo de parámetro T de una clase C se declara en , C <Derivado> puede ser de forma segura un supertipo de C <Base> .
Otra forma de recordarlo:
Consumidor dentro , productor fuera .
ver Varianza genérica de Kotlin
----------------- actualizado el 4 de enero de 2019 -----------------
Para el " Consumidor dentro, Productor fuera ", solo leemos del método Producer - call para obtener el resultado de tipo T; y solo escribir al método de llamada al consumidor pasando el parámetro de tipo T.
En el ejemplo de List<out T>
, es obvio que podemos hacer esto:
val n1: Number = numberList[0]
val n2: Number = doubleList[0]
Por lo tanto, es seguro proporcionarlo List<Double>
cuando List<Number>
se espera, por List<Number>
lo tanto, es un súper tipo de List<Double>
, pero no al revés.
En el ejemplo de Comparable<in T>
:
val double: Double = 1.0
doubleComparable.compareTo(double)
numberComparable.compareTo(double)
Por lo tanto, es seguro proporcionarlo Comparable<Number>
cuando Comparable<Double>
se espera, por Comparable<Double>
lo tanto, es un súper tipo de Comparable<Number>
, pero no al revés.
List<out T>
declaración de visualización es que laout
hace inmutable (en comparación con las colecciones mutables, que no tienen salida). Puede ser útil mencionarlo y enfatizarlo en la respuesta. La conversión implícita es una consecuencia de este en lugar del punto principal (dado que no se puede escribir en List <Number>, es seguro tenerlo como referencia a List <Double>).out
parte no es lo que lo haceList
inmutable. Puede crear fácilmente su propiaList<out T>
interfaz que tenga unclear()
método, ya que no requeriría ningún argumento.List<out T> is like List<? extends T> in Java
y
List<in T> is like List<? super T> in Java
Por ejemplo, en Kotlin puedes hacer cosas como
val value : List<Any> = listOf(1,2,3) //since List signature is List<out T> in Kotlin
fuente
List<out T>
significa que puede hacerloval list: List<Number> = listOf<Int>()
porqueInt
es un tipo derivado deNumber
. El Java equivalente seríaList<? extends Number> list = new ArrayList<Integer>();
Consulte el manual de Kotlin.
Y esto,
fuente
Recuerda así:
in
es "for in put": quieres poner (escribir) algo en él (por lo que es un "consumidor")out
es "para sacar ": quieres sacar (leer) algo (así que es un "productor")Si eres de Java,
<in T>
es para entrada, por lo que es como<? super T>
(consumidor)<out T>
es para salida, entonces es como<? extends T>
(productor)fuente