Kolekcje w Kotline, czyli małe rzeczy robią dużą różnicę

Jak przystało na nowocześnie zaprojektowany język programowania, Kotlin posiada kolekcje niezmienne i zmienne „na równych prawach”. W przeciwieństwie do Javy, gdzie kolekcje mutowane są preferowane na poziomie API (by zrobić kolekcję niemutowaną, trzeba się naklepać). BTW, wynika to prostego faktu – przed Javą 1.5 nie było metod o zmiennej liczbie argumentów, więc nie można było zaprojektować jakiegoś sensownego API.

Listing 1. Przykład tworzenie kolekcji

fun main(args: Array<String>) {
    
    val immute = listOf("Ania", "Ela", "Wojtek")
    val mutant = mutableListOf("Ania", "Ela", "Wojtek")
    mutant.add("Henio")
    
    println(immute)
    println(mutant)
}

Na tym poziomie nie ma tu nic zaskakującego. Ogólna konwencja w API jest taka, że mamy pary metod xOf i mutableXOf. Co ważne można w ten sposób tworzyć też mapy:

Listing 2. Tworzenie map

fun main(args: Array<String>) {

    val pierscienie = mapOf(9 to "ludzie", 7 to "Krasnoludów", 3 to "Elfy", 1 to "Sauron")

    println(pierscienie)

}

W sumie nie ma tu nic niezwykłego. Jest jednak jedna drobna rzecz, która powoduje, że Kotlin wyróżnia się spośród innych języków. Twórcy założyli, że kolekcje niezmienne będą kowariantne. To znaczy, jeżeli napiszemy:

Listing 3. Kowariancja kolekcji niezmiennych

fun main(args: Array<String>) {

    val rectangles = listOf(Rectangle())
    val shapses: List<Shape> = rectangles

}

To będzie to prawidłowy kod z punktu widzenia systemu typów. Inaczej mówiąc, kowariancja oznacza, iż lista kwadratów jest podtypem listy kształtów, ponieważ kwadrat jest podtypem kształtu. Tak samo zapisany kod dla list kształtów, która jest mutująca:

Listing 4. A tu się wywali

fun main(args: Array<String>) {

    val rectangles = listOf(Rectangle())
    val shapses: MutableList<Shape> = rectangles

}

Zwróci błąd nieprawidłowego typu. Mała rzecz, a cieszy. Wytłumaczenie tego zachowania jest oczywiste. Jeżeli lista kształtów może zmieniać zawartość, a „pod spodem“ jest lista kwadratów, to dodanie na przykład trójkąta spowoduje błąd. Tyle na dziś.

Jedna myśl na temat “Kolekcje w Kotline, czyli małe rzeczy robią dużą różnicę

Napisz odpowiedź

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax