Funções genéricas
Parte da seção Programação Orientada a Objetos do Journey de Kotlin da Coddy. Lição 37 de 57.
Uma função genérica funciona com qualquer tipo. Seu parâmetro de tipo, escrito entre sinais de menor e maior antes do nome da função, representa o tipo usado pelo chamador. T é o nome usual:
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())Saída:
4
NONEO Kotlin infere o argumento de tipo a partir dos argumentos. Quando não há nada a partir do qual inferi-lo, você mesmo o escreve, como em listOf<String>() acima:
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)Saída:
[ab, ab, ab]
[7, 7]
[]Uma função pode ter vários parâmetros de tipo, e um parâmetro de tipo função pode usá-los. É assim que funções de biblioteca como map funcionam para cada tipo de elemento e 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)))Saída:
[4, 3]
{1=a, 2=b}Um parâmetro de tipo preserva o tipo do chamador. firstOr(listOf(3, 5), 0) retorna um Int, então + 1 compila. Uma versão escrita para List<Any> também aceitaria qualquer lista, mas retornaria Any e exigiria uma conversão em cada chamada:
fun firstAny(list: List<Any>, default: Any): Any = if (list.isEmpty()) default else list[0]
// firstAny(listOf(3, 5), 0) + 1 // erro: Any não tem plus
(firstAny(listOf(3, 5), 0) as Int) + 1 // compila, mas precisa de um cast
firstOr(listOf(3, 5), 0) + 1 // genérico: o resultado é um IntDesafio
FácilEscreva duas funções genéricas que funcionem para listas de qualquer tipo. countWhere(items, predicate) retorna quantos elementos passam pelo predicado, uma função (T) -> Boolean. mostCommon(items) retorna o elemento que aparece com mais frequência (aquele que aparece primeiro na lista quando há empate nas contagens), ou null para uma lista vazia.
O código fornecido lê uma linha de palavras e uma linha de números, e imprime o número de palavras com mais de 3 letras, a palavra mais comum, o número de números pares, o número mais comum e nothing: null para uma lista vazia.
Seu código deve estar em ListTools.kt. Main.kt contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
fun main() {
// Código de entrada/saída fornecido: mantenha-o 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 lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesConstrutores PrimáriosBlocos init e ValidaçãoConstrutores SecundáriosRecapitulação - Cartão da Biblioteca4Herança
Classes Abertas e SubclassesSobrescrevendo Membrossuper e ConstrutoresClasses AbstratasRevisão - Diretório de Funcionários2Propriedades e Encapsulamento
Acessores PersonalizadosModificadores de VisibilidadeSetters Privadoslazy e lateinitRevisão - Conta Bancária5Interfaces
Declarando InterfacesMétodos PadrãoMúltiplas InterfacesInterfaces como TiposRecapitulação - Métodos de Pagamento8Genéricos
Funções genéricasClasses genéricasRestrições de tipoVariância com in e outRecapitulação - Fila de prioridade11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Playground de Kotlin