Kotlin
Generics
Ricerca…
introduzione
Una lista può contenere numeri, parole o qualsiasi cosa. Ecco perché chiamiamo la lista generica .
Generics sono fondamentalmente usati per definire quali tipi una classe può contenere e quale tipo un oggetto detiene attualmente.
Sintassi
- class ClassName < TypeName >
- class ClassName <*>
- ClassName <in UpperBound >
- ClassName <out LowerBound >
- Classe Nome <TypeName: upper bound>
Parametri
Parametro | Dettagli |
---|---|
TypeName | Tipo Nome del parametro generico |
Limite superiore | Tipo covariante |
Limite inferiore | Tipo controvariante |
Nome della classe | Nome della classe |
Osservazioni
Implied Upper Bound è Nullable
In Kotlin Generics, il limite superiore del parametro di tipo T
sarebbe Any?
. Pertanto per questa classe:
class Consumer<T>
Il parametro type T
è davvero T: Any?
. Per rendere un limite superiore non nullable, T: Any
esplicitamente specifico. Per esempio:
class Consumer<T: Any>
Variante del sito di dichiarazione
La varianza del sito di dichiarazione può essere considerata come dichiarazione della varianza del sito di utilizzo una volta per tutte i siti di utilizzo.
class Consumer<in T> { fun consume(t: T) { ... } }
fun charSequencesConsumer() : Consumer<CharSequence>() = ...
val stringConsumer : Consumer<String> = charSequenceConsumer() // OK since in-projection
val anyConsumer : Consumer<Any> = charSequenceConsumer() // Error, Any cannot be passed
val outConsumer : Consumer<out CharSequence> = ... // Error, T is `in`-parameter
Gli esempi diffusi di varianza del sito di dichiarazione sono List<out T>
, che è immutabile in modo che T
appaia solo come tipo di valore di ritorno, e Comparator<in T>
, che riceve solo T
come argomento.
Scostamento del sito d'uso
La varianza del sito di utilizzo è simile ai caratteri jolly Java:
Out-proiezione:
val takeList : MutableList<out SomeType> = ... // Java: List<? extends SomeType>
val takenValue : SomeType = takeList[0] // OK, since upper bound is SomeType
takeList.add(takenValue) // Error, lower bound for generic is not specified
In proiezione:
val putList : MutableList<in SomeType> = ... // Java: List<? super SomeType>
val valueToPut : SomeType = ...
putList.add(valueToPut) // OK, since lower bound is SomeType
putList[0] // This expression has type Any, since no upper bound is specified
Star-proiezione
val starList : MutableList<*> = ... // Java: List<?>
starList[0] // This expression has type Any, since no upper bound is specified
starList.add(someValue) // Error, lower bound for generic is not specified
Guarda anche:
Interoperabilità di Variant Generics quando si chiama Kotlin da Java.