Sobes.tech
Junior — Middle

Pode explicar o conceito de contravariância nos genéricos do Kotlin e como ele afeta a segurança de tipos?

sobes.tech IA

Resposta da IA

A contravariância em Kotlin é indicada pela palavra-chave in e aplica-se aos parâmetros de tipo em genéricos que são usados apenas para aceitar valores (parâmetros de entrada). Isso significa que se você tiver uma classe Consumer<in T>, então Consumer<SuperType> pode ser atribuído a uma variável de tipo Consumer<SubType>, ou seja, a direção da substituição de tipos é oposta à herança.

Isso ajuda a garantir a segurança de tipos, permitindo usar um tipo mais geral onde se espera um mais específico, mas proibindo operações que possam causar erros em tempo de execução.

Exemplo:

interface Consumer<in T> {
    fun consume(item: T)
}

open class Animal
class Cat : Animal()

fun feedCat(consumer: Consumer<Cat>) {
    consumer.consume(Cat())
}

val animalConsumer: Consumer<Animal> = object : Consumer<Animal> {
    override fun consume(item: Animal) {
        println("Alimentar o animal")
    }
}

// Graças à contravariância, é possível passar um Consumer<Animal> onde se espera um Consumer<Cat>
feedCat(animalConsumer)

Aqui, Consumer<Animal> pode ser usado como Consumer<Cat> porque Consumer é contravariável em relação ao tipo T. Isso previne erros relacionados ao uso incorreto de tipos e permite trabalhar de forma flexível com tipos genéricos.