Funciones genéricas
Parte de la sección Programación orientada a objetos del Journey de Kotlin de Coddy. Lección 37 de 57.
Una función genérica funciona con cualquier tipo. Su parámetro de tipo, escrito entre corchetes angulares antes del nombre de la función, representa el tipo que utiliza quien llama a la función. T es el nombre habitual:
fun <T> firstOr(list: List<T>, default: T): T = if (list.isEmpty()) default else list[0]Dentro de main:
println(firstOr(listOf(3, 5), 0) + 1)
println(firstOr(listOf<String>(), "none").uppercase())Salida:
4
NONEKotlin infiere el argumento de tipo a partir de los argumentos. Cuando no hay nada de lo que inferirlo, lo escribes tú mismo, como en listOf<String>() arriba:
fun <T> repeatItem(item: T, times: Int): List<T> = List(times) { item }Dentro de main:
println(repeatItem("ab", 3))
println(repeatItem(7, 2))
val empty = repeatItem<Double>(1.5, 0)
println(empty)Salida:
[ab, ab, ab]
[7, 7]
[]Una función puede tener varios parámetros de tipo, y un parámetro de tipo función puede utilizarlos. Así es como funcionan las funciones de biblioteca como map para cualquier tipo de elemento y de resultado:
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 }Dentro de main:
println(transform(listOf("kiwi", "fig")) { it.length })
println(invert(mapOf("a" to 1, "b" to 2)))Salida:
[4, 3]
{1=a, 2=b}Un parámetro de tipo conserva el tipo del llamador. firstOr(listOf(3, 5), 0) devuelve un Int, por lo que + 1 se compila. Una versión escrita para List<Any> también aceptaría cualquier lista, pero devolvería Any y obligaría a hacer una conversión de tipo en cada llamada:
fun firstAny(list: List<Any>, default: Any): Any = if (list.isEmpty()) default else list[0]
// firstAny(listOf(3, 5), 0) + 1 // error: Any no tiene plus
(firstAny(listOf(3, 5), 0) as Int) + 1 // compila, pero necesita un cast
firstOr(listOf(3, 5), 0) + 1 // genérico: el resultado es un IntDesafío
FácilEscribe dos funciones genéricas que funcionen con listas de cualquier tipo. countWhere(items, predicate) devuelve cuántos elementos cumplen el predicado, una función (T) -> Boolean. mostCommon(items) devuelve el elemento que aparece con mayor frecuencia (el que aparece primero en la lista cuando hay empate en los recuentos), o null para una lista vacía.
El código proporcionado lee una línea de palabras y una línea de números, e imprime la cantidad de palabras con más de 3 letras, la palabra más común, la cantidad de números pares, el número más común y nothing: null para una lista vacía.
Tu código va en ListTools.kt. Main.kt contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
fun main() {
// Código de entrada/salida suministrado: déjalo como está
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>())}")
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesConstructores primariosBloques init y validaciónConstructores secundariosRepaso - Tarjeta de biblioteca4Herencia
Clases abiertas y subclasesSobrescritura de miembrossuper y constructoresClases abstractasRepaso: directorio del personal2Propiedades y encapsulación
Accesores personalizadosModificadores de visibilidadSetters privadoslazy y lateinitRepaso: cuenta bancaria5Interfaces
Declaración de interfacesMétodos predeterminadosInterfaces múltiplesInterfaces como tiposRepaso: métodos de pago8Genéricos
Funciones genéricasClases genéricasRestricciones de tiposVariancia con in y outRepaso - Cola de prioridad11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de librosPractica por tu cuenta: Playground de Kotlin