Fonctions génériques
Fait partie de la section Programmation orientée objet du Journey Kotlin de Coddy. Leçon 37 sur 57.
Une fonction générique fonctionne avec n’importe quel type. Son paramètre de type, écrit entre chevrons avant le nom de la fonction, représente le type utilisé par l’appelant. T est le nom habituel :
fun <T> firstOr(list: List<T>, default: T): T = if (list.isEmpty()) default else list[0]Dans main :
println(firstOr(listOf(3, 5), 0) + 1)
println(firstOr(listOf<String>(), "none").uppercase())Sortie :
4
NONEKotlin déduit l’argument de type à partir des arguments. Lorsqu’il n’y a rien à partir de quoi le déduire, vous l’écrivez vous-même, comme dans listOf<String>() ci-dessus :
fun <T> repeatItem(item: T, times: Int): List<T> = List(times) { item }À l’intérieur de main :
println(repeatItem("ab", 3))
println(repeatItem(7, 2))
val empty = repeatItem<Double>(1.5, 0)
println(empty)Sortie :
[ab, ab, ab]
[7, 7]
[]Une fonction peut avoir plusieurs paramètres de type, et un paramètre de type fonction peut les utiliser. C’est ainsi que les fonctions de bibliothèque telles que map fonctionnent avec chaque type d’élément et de résultat :
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 }Dans main :
println(transform(listOf("kiwi", "fig")) { it.length })
println(invert(mapOf("a" to 1, "b" to 2)))Sortie :
[4, 3]
{1=a, 2=b}Un paramètre de type conserve le type de l’appelant. firstOr(listOf(3, 5), 0) renvoie un Int, donc + 1 est compilé. Une version écrite pour List<Any> accepterait également toutes les listes, mais elle renverrait Any et imposerait une conversion de type à chaque appel :
fun firstAny(list: List<Any>, default: Any): Any = if (list.isEmpty()) default else list[0]
// firstAny(listOf(3, 5), 0) + 1 // erreur : Any n'a pas de plus
(firstAny(listOf(3, 5), 0) as Int) + 1 // compile, mais nécessite un cast
firstOr(listOf(3, 5), 0) + 1 // générique : le résultat est un IntDéfi
FacileÉcrivez deux fonctions génériques qui fonctionnent avec des listes de n’importe quel type. countWhere(items, predicate) renvoie le nombre d’éléments qui satisfont le prédicat, une fonction (T) -> Boolean. mostCommon(items) renvoie l’élément qui apparaît le plus souvent (celui qui apparaît en premier dans la liste lorsque les occurrences sont à égalité), ou null pour une liste vide.
Le code fourni lit une ligne de mots et une ligne de nombres, puis affiche le nombre de mots de plus de 3 lettres, le mot le plus fréquent, le nombre de nombres pairs, le nombre le plus fréquent et nothing: null pour une liste vide.
Votre code doit se trouver dans ListTools.kt. Main.kt contient le code fourni d’entrée/sortie et ne peut pas être modifié.
Essayez vous-même
fun main() {
// Code d'entrée/sortie fourni : le garder tel quel
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>())}")
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Classes et objets
Travailler avec des fichiersDéfinir des classesConstructeurs primairesBlocs init et validationConstructeurs secondairesRécapitulatif - Carte de bibliothèque4Héritage
Classes ouvertes et sous-classesRedéfinition des membressuper et constructeursClasses abstraitesRécapitulatif – Annuaire du personnel2Propriétés et encapsulation
Accesseurs personnalisésModificateurs de visibilitéSetters privéslazy et lateinitRécapitulatif - Compte bancaire5Interfaces
Déclarer des interfacesMéthodes par défautInterfaces multiplesInterfaces en tant que typesRécapitulatif - Méthodes de paiement8Génériques
Fonctions génériquesClasses génériquesContraintes de typeVariance avec in et outRécapitulatif - File de priorité11Projet : Gestion de bibliothèque
Livres et membresEmprunter des livresEntraînez-vous par vous-même : Playground Kotlin