1
resposta

O que é invariance e covariance em koltin, minha afirmação está certa?

Invariance é representado pelo <T>

Se refere à situação em que nenhum relacionamento de subtipo é permitido entre tipos genéricos. Quando um tipo genérico é invariance, isso significa que não há relação entre Generic "A" e Generic "B ", mesmo se A e B estiverem relacionados por subtipagem. Não pode usar um tipo genérico onde é esperado outro tipo genérico que não seja exatamente o mesmo.

Covariance representado pelo <out T>

Em resumo é o oposto do invariance, com covariante a gente consegue utilizar o subtipo para relacionar as classes.

Exemplo de ivariance

public class Array <T> {}
public inline fun <reified @PureReifiable T> arrayOf(vararg elements: T): Array<T>

ou seja se eu usar o código dessa forma, não vai funcionar

var exemplo1 = arrayOf<Int>(1)
var exemplo2 = arrayOf<Number>(1)

exemplo1 = exemplo2
    
ERROR: 	
    
Type mismatch.
Required: Array<Int>
Found: Array<Number>

Aqui tentei aplicar o covariance

Fiz o seguinte, repliquei assinatura e coloquei o out, mesmo assim não funcionou. Caso as informações acima esteja certa, o que há de errado com o código abaixo?

fun covarianceTest() {
  var exemplo1 = arrayOf2<Int>(1)
  var exemplo2 = arrayOf2<Number>(1)
    exemplo1 = exemplo2
}

inline fun <out T> arrayOf2(vararg elements: T): Array2<out T>{

}

class Array2<out T>{
    val nome:String = ""
}
1 resposta

Olá Thailan! Tudo bem?

Você fez uma boa descrição dos conceitos de invariance e covariance em Kotlin. Vamos dar uma olhada no que pode estar errado com o seu código de covariance.

Primeiro, é importante entender que a palavra-chave out em Kotlin indica que o tipo genérico pode ser retornado (produzido) pela classe, mas não consumido como entrada. Isso permite a atribuição de um tipo genérico a um tipo mais genérico (um supertipo).

No seu exemplo, você definiu a função arrayOf2 e a classe Array2 corretamente com o uso de out. No entanto, o problema está na tentativa de atribuir exemplo1 = exemplo2. Mesmo com o uso de out, o Kotlin não permite a atribuição direta de tipos genéricos de forma covariante em variáveis locais devido a questões de segurança de tipo e consistência. A covariância permite a leitura de dados de uma estrutura de dados de forma segura, mas não a escrita ou reatribuição direta de variáveis.

Aqui está uma maneira de usar a covariância corretamente:

fun covarianceTest() {
    val exemplo1: Array2<Int> = arrayOf2(1)
    val exemplo2: Array2<Number> = arrayOf2(1)
    val exemplo3: Array2<Number> = exemplo1 // Isso é permitido devido à covariância

    // exemplo1 = exemplo2 // Isso não é permitido e causará erro
}

inline fun <out T> arrayOf2(vararg elements: T): Array2<out T> {
    return Array2()
}

class Array2<out T> {
    val nome: String = ""
}

Neste exemplo, exemplo3 pode ser atribuído a partir de exemplo1 porque Array2<Int> é um subtipo de Array2<Number> devido ao uso de out. No entanto, a reatribuição direta de exemplo1 para exemplo2 não é permitida.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software