Funkcje generyczne
Część sekcji Programowanie obiektowe ścieżki Kotlin w Coddy. Lekcja 37 z 57.
Funkcja generyczna działa z dowolnym typem. Jej parametr typu, zapisany w nawiasach ostrych przed nazwą funkcji, oznacza typ używany przez wywołującego. T to zwyczajowa nazwa:
fun <T> firstOr(list: List<T>, default: T): T = if (list.isEmpty()) default else list[0]Wewnątrz main:
println(firstOr(listOf(3, 5), 0) + 1)
println(firstOr(listOf<String>(), "none").uppercase())Wynik:
4
NONEKotlin wywnioskuje argument typu na podstawie argumentów. Gdy nie ma podstaw, by go wywnioskować, wpisujesz go samodzielnie, jak w przypadku listOf<String>() powyżej:
fun <T> repeatItem(item: T, times: Int): List<T> = List(times) { item }Wewnątrz main:
println(repeatItem("ab", 3))
println(repeatItem(7, 2))
val empty = repeatItem<Double>(1.5, 0)
println(empty)Wynik:
[ab, ab, ab]
[7, 7]
[]Funkcja może mieć kilka parametrów typów, a parametr typu funkcyjnego może ich używać. Tak działają funkcje biblioteczne, takie jak map, dla każdego typu elementu i wyniku:
fun <A, B> transform(items: List<A>, f: (A) -> B): List<B> {
val out = mutableListOf<B>()
for (item in items) out.add(f(item))
return out
}
fun <K, V> invert(map: Map<K, V>): Map<V, K> = map.entries.associate { (k, v) -> v to k }Wewnątrz main:
println(transform(listOf("kiwi", "fig")) { it.length })
println(invert(mapOf("a" to 1, "b" to 2)))Wynik:
[4, 3]
{1=a, 2=b}Parametr typu zachowuje typ przekazany przez wywołującego. firstOr(listOf(3, 5), 0) zwraca Int, więc + 1 się kompiluje. Wersja napisana dla List<Any> również przyjęłaby każdą listę, ale zwracałaby Any i wymagałaby rzutowania przy każdym wywołaniu:
fun firstAny(list: List<Any>, default: Any): Any = if (list.isEmpty()) default else list[0]
// firstAny(listOf(3, 5), 0) + 1 // błąd: Any nie ma operatora plus
(firstAny(listOf(3, 5), 0) as Int) + 1 // kompiluje się, ale wymaga rzutowania
firstOr(listOf(3, 5), 0) + 1 // generyczna: wynik jest typu IntWyzwanie
ŁatwyNapisz dwie funkcje generyczne, które działają z listami dowolnego typu. countWhere(items, predicate) zwraca liczbę elementów spełniających predykat, czyli funkcję (T) -> Boolean. mostCommon(items) zwraca element, który pojawia się najczęściej (ten, który pojawia się jako pierwszy na liście, gdy liczby wystąpień są równe), lub null dla pustej listy.
Dostarczony kod odczytuje wiersz słów i wiersz liczb, a następnie wyświetla liczbę słów dłuższych niż 3 litery, najczęściej występujące słowo, liczbę liczb parzystych, najczęściej występującą liczbę oraz nothing: null dla pustej listy.
Umieść swój kod w pliku ListTools.kt. Main.kt zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
fun main() {
// Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
val input = generateSequence(::readLine).toList()
val words = input[0].split(" ")
val numbers = input[1].split(" ").map { it.toInt() }
println("long words: ${countWhere(words) { it.length > 3 }}")
println("most common word: ${mostCommon(words)}")
println("even numbers: ${countWhere(numbers) { it % 2 == 0 }}")
println("most common number: ${mostCommon(numbers)}")
println("nothing: ${mostCommon(listOf<String>())}")
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasKonstruktory główneBloki init i walidacjaKonstruktory dodatkowePodsumowanie — karta biblioteczna4Dziedziczenie
Klasy otwarte i podklasyNadpisywanie składowychsuper i konstruktoryKlasy abstrakcyjnePodsumowanie – katalog pracowników7Klasy specjalne
Klasy danychKlasy wyliczenioweHierarchie zapieczętowaneequals, hashCode, toStringPodsumowanie — śledzenie zamówień10Wzorce projektowe, część 2
Delegowanie za pomocą byWzorzec dekoratoraWzorzec budowniczegoWzorzec stanu2Właściwości i hermetyzacja
Własne akcesoryModyfikatory widocznościPrywatne setterylazy i lateinitPowtórka – konto bankowe5Interfejsy
Deklarowanie interfejsówMetody domyślneWiele interfejsówInterfejsy jako typyPowtórzenie – metody płatności8Typy generyczne
Funkcje generyczneKlasy generyczneOgraniczenia typówKowariancja i kontrawariancja: in i outPodsumowanie — kolejka priorytetowa11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Edytor online Kotlin