Kotlin
Generics
Szukaj…
Wprowadzenie
Lista może zawierać liczby, słowa lub cokolwiek innego. Dlatego nazywamy Listę ogólną .
Generyczne są zasadniczo używane do definiowania, jakie typy może przechowywać klasa i jaki typ obiekt obecnie posiada.
Składnia
- Klasa ClassName <TypeName>
- klasa nazwa_klasy <*>
- ClassName <w UpperBound >
- ClassName <out LowerBound >
- Nazwa klasy <TypeName: górna granica>
Parametry
Parametr | Detale |
---|---|
Wpisz imię | Typ Nazwa parametru ogólnego |
Górna granica | Typ kowariantny |
Dolna granica | Typ przeciwstawny |
Nazwa klasy | Nazwa klasy |
Uwagi
Implikowana górna granica jest zerowalna
W Kotlin Generics górną granicą parametru typu T
byłoby Any?
. Dlatego dla tej klasy:
class Consumer<T>
Parametr typu T
to tak naprawdę T: Any?
. Aby utworzyć górną granicę, która nie ma wartości zerowej, należy jawnie określić T: Any
. Na przykład:
class Consumer<T: Any>
Wariancja strony deklaracji
Wariancja strony deklaracyjnej może być traktowana jako deklaracja wariancji witryny użytkowania raz na zawsze dla wszystkich stron docelowych.
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
Powszechnymi przykładami wariancji strony deklaracji są List<out T>
, który jest niezmienny, tak że T
pojawia się tylko jako typ wartości zwracanej, oraz Comparator<in T>
, który otrzymuje tylko T
jako argument.
Warianty użytkowania witryny
Wariant użycia witryny jest podobny do symboli wieloznacznych Java:
Prognozowanie:
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
Projekcja:
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
Projekcja gwiazdy
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
Zobacz też:
Współdziałanie Variant Generics podczas wywoływania Kotlin z Java.