0Pricing
Kotlin Academy · Aula

Funções genéricas e restrições de tipos com where

Escreva funções genéricas com uma ou várias restrições de tipos.

Funções genéricas e restrições de tipos com where é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.

Fundamentos de funções genéricas

Funções genéricas usam parâmetros de tipo entre sinais de menor e maior antes do nome da função. O parâmetro de tipo pode ser usado nos tipos dos parâmetros e nos tipos de retorno.

fun <T> identity(value: T): T = value
fun <T> listOf2(a: T, b: T): List<T> = listOf(a, b)
fun main() {
    println(identity(42))       // 42
    println(identity("hello"))  // hello
    println(listOf2(1, 2))      // [1, 2]
}

Limites superiores com a restrição :

Restrinja um parâmetro de tipo com um limite superior usando :. O tipo deve ser um subtipo do limite.

fun <T : Comparable<T>> max(a: T, b: T): T = if (a >= b) a else b
fun main() {
    println(max(3, 7))          // 7
    println(max("apple", "banana")) // banana
    // max(listOf(1), listOf(2)) // error: List is not Comparable
}

Limite superior anulável

O limite superior padrão é Any? (anulável). Use T : Any para excluir nulos.

fun <T : Any> notNull(value: T?): T {
    return value ?: throw IllegalArgumentException("Value is null")
}
fun main() {
    println(notNull("hello"))  // hello
    try { notNull(null) } catch (e: Exception) { println(e.message) }
}

Várias restrições com where

Use a cláusula where para aplicar várias restrições a um único parâmetro de tipo.

fun <T> process(item: T): String
        where T : Comparable<T>, T : CharSequence {
    return "Length=${item.length}, sorted=${item > "a"}"
}
fun main() {
    println(process("kotlin")) // Length=6, sorted=true
    // process(42) // error: Int doesn't implement CharSequence
}

Cláusula de restrições em uma classe

A cláusula where também funciona com parâmetros de tipo no nível da classe.

class SortedContainer<T>(private val items: MutableList<T> = mutableListOf())
        where T : Comparable<T>, T : Any {
    fun add(item: T) { items.add(item); items.sort() }
    fun top(): T? = items.lastOrNull()
}
fun main() {
    val c = SortedContainer<Int>()
    c.add(5); c.add(2); c.add(8)
    println(c.top()) // 8
}

Funções genéricas de extensão

As funções de extensão também podem ter parâmetros de tipo, tornando-se disponíveis em tipos genéricos específicos.

fun <T : Comparable<T>> List<T>.second(): T? {
    return if (size >= 2) this[1] else null
}
fun main() {
    println(listOf(10, 20, 30).second()) // 20
    println(listOf("a").second())        // null
}

Parâmetro de tipo na posição de retorno

As funções genéricas podem inferir o tipo a partir do contexto, evitando argumentos de tipo explícitos no ponto de chamada.

fun <T> MutableList<T>.popOrDefault(default: T): T {
    return if (isEmpty()) default else removeAt(lastIndex)
}
fun main() {
    val list = mutableListOf(1, 2, 3)
    println(list.popOrDefault(0)) // 3
    println(list.popOrDefault(0)) // 2
    println(mutableListOf<Int>().popOrDefault(-1)) // -1
}

Utilitários genéricos reutilizáveis

As funções genéricas tornam as funções utilitárias reutilizáveis entre tipos, sem duplicação.

fun <T> Iterable<T>.firstOrElse(default: T): T = firstOrNull() ?: default
fun <T, R : Comparable<R>> Iterable<T>.maxByOrElse(selector: (T) -> R, default: T): T =
    maxByOrNull(selector) ?: default
fun main() {
    println(listOf<String>().firstOrElse("fallback")) // fallback
    println(listOf("a","bbb","cc").maxByOrElse({ it.length }, "")) // bbb
}

Projeção estrela versus curinga limitado

Compare o uso de um parâmetro de tipo limitado (útil quando é necessário produzir ou consumir T) com a projeção estrela (quando o tipo é desconhecido).

fun <T : Number> sumList(list: List<T>): Double =
    list.sumOf { it.toDouble() }
// Star projection: read-only, type unknown
fun printAll(list: List<*>) = list.forEach { println(it) }
fun main() {
    println(sumList(listOf(1, 2, 3)))    // 6.0
    printAll(listOf("a", 1, true))       // a, 1, true
}

Troca genérica de pares

Uma função genérica simples, mas ilustrativa, que inverte os componentes de um par.

fun <A, B> Pair<A, B>.swap(): Pair<B, A> = Pair(second, first)
fun main() {
    val pair = Pair("hello", 42)
    val swapped = pair.swap()
    println(swapped) // (42, hello)
}

Prática: descompactador genérico de resultados

Use genéricos limitados para escrever um utilitário que aplica uma transformação tipada a um Result<T>.

fun <T : Any, R : Any> Result<T>.mapNotNull(transform: (T) -> R?): Result<R> {
    return fold(
        onSuccess = { v ->
            val r = transform(v)
            if (r != null) Result.success(r) else Result.failure(NoSuchElementException())
        },
        onFailure = { Result.failure(it) }
    )
}
fun main() {
    val r = Result.success("123")
    val n = r.mapNotNull { it.toIntOrNull() }
    println(n) // Success(123)
}

Verificação rápida

Como aplicar várias restrições a um único parâmetro de tipo?

Revisão

As funções genéricas usam parâmetros de tipo para escrever código reutilizável e seguro quanto aos tipos. Use : para uma única restrição ou where para várias. O compilador do Kotlin impõe essas restrições no ponto de chamada.

Perguntas Frequentes

A aula “Funções genéricas e restrições de tipos com where” é grátis?

Sim — o texto completo de “Funções genéricas e restrições de tipos com where” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.

O que vou aprender em “Funções genéricas e restrições de tipos com where”?

Escreva funções genéricas com uma ou várias restrições de tipos. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Kotlin Academy?

Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Funções genéricas e restrições de tipos com where”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Kotlin Academy?

Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Funções genéricas e restrições de tipos com where
  2. Variância no local da declaração: in e out
  3. Projeção estrela e quando usar *
  4. Apagamento de tipos e parâmetros de tipo reified
← Voltar para Kotlin Academy