Luiz H. Rapatão

Luiz H. Rapatão

Senior Software Engineer

4 Minutos De Leitura

Destructuring em Kotlin

Destructuring é um conceito de programação que envolve dividir uma estrutura de dados complexa em seus componentes individuais e atribuir esses componentes a variáveis individuais diretamente em uma única instrução.

Como muitas outras linguagens modernas suportam, mas Kotlin, pelo menos quando comparado a JavaScript, tem um comportamento diferente quando usado em classes de dados.

O objetivo deste texto é falar sobre essa diferença, e como prevenir, o mais cedo possível, erros que seu uso possa causar ao seu código.

Como utilizar desestruturação

Destructuring permite decompor um objeto em um conjunto de variáveis. Por exemplo:

data class Item(val name: String, val price: Double)

val rice = Item("Rice", 2.13)
val (name, price) = rice

Neste código, uma nova instância Item foi criada e desestruturada em duas variáveis que representam seus atributos.

Isso foi alcançado usando a seguinte declaração:

val (name, price) = rice

Neste caso foi utilizada uma data class, mas também é possível utilizá-la em outras estruturas de dados, como Arrays, Listas ou outras classes.

val list = listOf("element 1", "element 2")
val (l1, l2) = list

val array = arrayOf("element 1", "element 2", "element 3")
val (a1, a2) = array

Como foi possível notar no exemplo do array, não é obrigatório ter todos os elementos atribuídos às variáveis. Valores não mapeados são simplesmente ignorados.

Importante: mapear mais elementos do que os existentes na lista lançará java.lang.ArrayIndexOutOfBoundsException

A ordem é importante

A diferença mais significativa entre Destructuring em Kotlin, quando comparado a JavaScript é que a ordem dos elementos é importante.

Em JavaScript, assim como em Kotlin, a desestruturação de uma coleção é baseada em ordem, o que significa que a primeira declaração de variável será atribuída ao primeiro elemento da coleção, a segunda variável ao segundo elemento e assim por diante …

A diferença entre essas duas linguagens está na desestruturação de objetos, onde em JavaScript extrai as propriedades do objeto usando seu nome declarado e Kotlin extrai com base na ordem de declaração.

Em JavaScript, tendo o seguinte objeto:

let rice = {name: "Rice", price: 2.13};

É possível destruí-lo usando ambas as instruções, e ambas sempre terão o mesmo resultado:

let {name, price} = rice; // name = "Rice", price = 2.13
let {price, name} = rice; // price = 2.13, name = "Rice"

Em Kotlin, tendo o objeto Rice:

data class Item(val name: String, val price: Double)
val rice = Item("Rice", 2.13)

A ordem da declaração é importante ao desestrutura-la:

val (name, price) = rice // name = "Rice", price = 2.13
val (price, name) = rice // price = "Rice", name = 2.13

Como você pode ver, a ordem em que cada atributo do Item é declarado impacta diretamente na sua atribuição no momento da desestruturação do mesmo.

Definindo o tipo das variáveis

Como você pode imaginar, isso pode causar algum comportamento indesejado em sua aplicação ao utilizá-la, e você pode estar pensando se é possível mudar seu comportamento, e a resposta é: não.

Embora não seja possível alterar, entender esse comportamento pode ajudar a prevenir problemas relacionados a ele, ao ter casos de teste que cobrem explicitamente alterações equivocadas relacionadas aos campos utilizados e também, quando possível, impor o tipo de dados.

A aplicação do tipo de dados torna alterações como essa perceptíveis no momento da compilação.

Ao alterar a atribuição mostrada anteriormente neste texto, você pode ter um erro de compilação caso a classe de dados utilizada tenha sua ordem de campos alterada.

val (name: String, price: Double) = rice // name = "Rice", price = 2.13

Portanto, se alguém alterar o Item para que o atributo price seja declarado primeiro, a digitação não corresponderá e a compilação não será bem-sucedida.

Como você pode imaginar, isso não evitou todos os casos porque se esses dois campos tiverem o mesmo tipo de dados, a compilação será bem-sucedida, pois ainda coincidem. Para casos como este, ter bons casos de teste é a única solução eficaz.

A aplicação do tipo de dados apenas traz ao seu código outra validação, o que pode ser útil e, geralmente, mais fácil de identificar a parte exata do código que foi impactada por uma alteração.

Usando com sabedoria

Embora as declarações de desestruturação possam tornar o código mais breve e expressivo, evite usá-las em excesso. O uso excessivo pode dificultar a compreensão do código, especialmente para quem não está familiarizado com o recurso.

Sempre priorize a legibilidade e a facilidade de manutenção e lembre-se, só porque você pode, nem sempre significa que deve.

Concluindo, as declarações de desestruturação do Kotlin são uma ótima ferramenta para simplificar seu código e torná-lo mais expressivo quando usado criteriosamente. Eles fornecem uma maneira de desestruturar um objeto em diversas variáveis, tornando o código mais conciso e legível. No entanto, como todas as ferramentas, elas devem ser usadas de forma adequada e com compreensão de sua mecânica subjacente.

Posts Recentes