Kotlin Academy · Lektion

Varians på anvendelsesstedet

Typeprojektioner

Lektion 3 af 413 trin

Varians på anvendelsesstedet er en gratis Kotlin Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Kotlin Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Kotlin Academy-kurset indeholder 4 lektioner i alt.

Varians ved anvendelsesstedet

Nogle gange er en generisk klasse invariant som helhed, men en bestemt funktion producerer eller modtager kun typen. Varians ved anvendelsesstedet, også kaldet typeprojektioner, anvender out eller in præcis dér, hvor en type bruges.

Hvorfor bruge varians ved anvendelsesstedet?

En invariant klasse som MutableList<T> kan ikke gøres kovariant ved deklarationen, fordi den både læser og skriver T. En bestemt funktion læser måske kun fra den, og projektioner lader os udtrykke det sikkert.

out-projektion

Når du skriver Array<out T> som parametertype, får du en kovariant visning: Du kan læse T, men ikke skrive til den. Det lader dig sende en Array<String>, hvor der forventes en Array<out Any>.

fun printArray(items: Array<out Any>) {
    for (item in items) println(item)
}

fun main() {
    val names: Array<String> = arrayOf("Ann", "Bob")
    printArray(names)
}

Kun læsning

Med en out-projektion tillader compileren læsning, altså uddata, men forbyder skrivning, altså inddata, fordi skrivning kan bryde typesikkerheden for det oprindelige array.

in-projektion

Når du skriver Array<in T>, får du en kontravariant visning: Du kan skrive T ind i den, men ved læsning kommer værdierne tilbage som Any?. Det lader dig acceptere arrayer af T eller en hvilken som helst supertype.

fun fill(dest: Array<in Int>, value: Int) {
    for (i in dest.indices) dest[i] = value
}

fun main() {
    val numbers: Array<Number> = arrayOf(0, 0, 0)
    fill(numbers, 7)
    println(numbers.toList())
}

Kun skrivning

Med en in-projektion må du skrive værdier af T, altså inddata, men elementtypen ses som top-typen ved læsning, eftersom den faktiske elementtype kan være en hvilken som helst supertype.

Projektioner og varians ved deklarationsstedet

Varians ved deklarationsstedet (class Box<out T>) gælder overalt, hvor klassen bruges. Projektioner ved anvendelsesstedet (Box<out T> som parameter) gælder kun dette ene sted. Brug projektioner, når selve klassen skal forblive invariant.

Stjerneudprojektionen

Når du slet ikke interesserer dig for typeargumentet, skal du bruge stjerneudprojektionen *. List<*> betyder en liste med en ukendt type; du kan læse elementer som den øvre grænse, men du kan ikke skrive sikkert til listen.

fun printSize(collection: List<*>) {
    println("Size: ${collection.size}")
}

fun main() {
    printSize(listOf(1, 2, 3))
    printSize(listOf("a", "b"))
}

Begrænsninger ved stjerneudprojektion

Med * kan du stadig kalde medlemmer, der er uafhængige af typen, som size, og læse elementer som Any?, men du kan ikke tilføje elementer, fordi den faktiske type er ukendt.

fun main() {
    val unknown: List<*> = listOf("x", "y")
    val first: Any? = unknown.first()
    println(first)
}

Valg af projektion

Brug out T, når en funktion kun læser, in T, når den kun skriver, og *, når den nøjagtige type er irrelevant. Disse projektioner gør invariantte klasser anvendelige på fleksible og typesikre måder.

Forholdet til Javas jokertegn

Kotlin-projektionerne out T og in T svarer til Javas jokertegn ? extends T og ? super T. Hvis du kender generiske typer i Java, vil projektioner føles velkendte.

Hurtigt tjek

Hvad kan du gøre med en parameter, der er skrevet som Array<out Any>?

Opsummering

Varians på brugsstedet anvender out-projektioner (skrivebeskyttede) eller in-projektioner (skriveorienterede) ved en bestemt brug, og * som stjerneudprojektion, når typen er ukendt. Det gør invariantte klasser fleksible uden at ændre deres deklaration. Derefter skal du begrænse typeparametre med generiske begrænsninger.

Gratis at komme i gang

Lær Kotlin med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
51
Lektioner
203

Ofte stillede spørgsmål

Er lektionen “Varians på anvendelsesstedet” gratis?

Ja — alle 3 lektioner i læringssporet Kotlin Academy, inklusive “Varians på anvendelsesstedet”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Kotlin Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Varians på anvendelsesstedet”?

Typeprojektioner Du øver dig i Kotlin Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Kotlin Academy?

Der kræves ingen tidligere erfaring. Kotlin Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Varians på anvendelsesstedet”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Kotlin Academy-lektion?

Ja. Alle Kotlin Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Generiske funktioner og klasser
  2. Varians på deklarationsstedet
  3. Varians på anvendelsesstedet
  4. Generiske begrænsninger
← Tilbage til Kotlin Academy