Destructuring declaration es una característica de Kotlin que permite descomponer un objeto en varias variables en una sola expresión. La construcción val (name, age) = user declara simultáneamente dos variables, asignándoles valores de los componentes del objeto. Según la documentación de Kotlin (2026), la desestructuración reduce el volumen de código al trabajar con data classes en un 30–50%. Destructuring declaration hace que el código sea más conciso y legible.
Puntos clave
val (a, b) = obj para descomponer un objeto en variablesDestructuring declaration (declaración de desestructuración) es una construcción sintáctica de Kotlin que permite descomponer una instancia de clase en varias variables en una sola expresión. El lado izquierdo contiene una lista de variables entre paréntesis, el lado derecho contiene el objeto que se descompone. Kotlin llama automáticamente a la función componentN() correspondiente para cada variable, donde N es el número ordinal de la variable entre paréntesis.
La declaración de desestructuración se usa más comúnmente con data classes. El compilador de Kotlin genera automáticamente component1(), component2(), etc., para cada data class, según la cantidad de propiedades en el constructor primario. Para las clases normales sin el modificador data, no se generan componentN(), pero se pueden definir manualmente como funciones operador con la palabra clave operator.
La declaración de desestructuración se ha convertido en un patrón popular debido a su capacidad para simplificar el código al trabajar con colecciones de pares, resultados de funciones e iteración de Map. En lugar de escribir person.firstName, person.lastName, el desarrollador escribe val (firstName, lastName) = person. Esto reduce la cantidad de líneas y mejora la legibilidad, especialmente en bucles y lambdas.
Al encontrar la construcción val (a, b) = obj, el compilador de Kotlin genera el siguiente código: val a = obj.component1(); val b = obj.component2(). Si las variables se declaran con var, se generan asignaciones var. El tipo de cada variable se deduce del tipo de retorno de la función componentN() correspondiente. Esto significa que la declaración de desestructuración es completamente segura en cuanto a tipos y se verifica en tiempo de compilación.
data class Person(val firstName: String, val lastName: String, val age: Int)
fun main() {
val person = Person("Alice", "Smith", 30)
// Destructuring: component1(), component2(), component3()
val (firstName, lastName, age) = person
println("$firstName $lastName, $age años")
}
En el listado, Person es una data class con tres propiedades. Kotlin genera component1() → firstName, component2() → lastName, component3() → age. La expresión val (firstName, lastName, age) = person llama a estas funciones y asigna los resultados. Es importante destacar: los nombres de las variables no necesitan coincidir con los nombres de las propiedades — el compilador solo observa el orden de componentN() y sus tipos. Se pueden descomponer solo las primeras N propiedades, ignorando el resto.
Las data classes son los candidatos principales para la declaración de desestructuración. Cada data class obtiene automáticamente componentN() para todas las propiedades del constructor primario. El orden de componentN() corresponde al orden de declaración de las propiedades. Esto significa que al cambiar el orden de los campos en una data class, también cambia el orden de las variables en la desestructuración, lo que puede provocar errores sutiles.
// Pair destructuring
val pair = Pair("key", 42)
val (key, value) = pair
println("$key -> $value")
// Triple destructuring
val triple = Triple("A", "B", "C")
val (first, second, third) = triple
// Map.Entry en bucle
val map = mapOf("a" to 1, "b" to 2)
for ((k, v) in map) {
println("$k = $v")
}
Pair y Triple son clases estándar con desestructuración incorporada para dos y tres componentes. Pair se usa a menudo como tipo de retorno para funciones que necesitan devolver dos valores relacionados sin crear una data class separada. En un bucle for sobre Map.Entry, la construcción (k, v) = entry desestructura la clave y el valor mediante component1() y component2(). Este es el patrón estándar para iterar sobre un Map en Kotlin, reemplazando completamente las llamadas explícitas a key y value.
Si algunos componentes no son necesarios durante la desestructuración, Kotlin permite reemplazarlos con un guion bajo _. Esto mejora la legibilidad — el lector ve inmediatamente que el componente se ignora. Además, el uso de _ evita el acceso accidental a una variable no inicializada: el compilador no crea ninguna variable para _, eliminando las advertencias sobre variables no utilizadas.
data class Order(
val id: Long,
val customerName: String,
val amount: Double,
val status: String
)
fun process(orders: List<Order>) {
for ((id, _, amount) in orders) {
println("Pedido $id: $amount")
}
}
En el listado, Order tiene cuatro propiedades, pero el bucle solo necesita id y amount. El guion bajo en lugar de customerName le dice al compilador “omite component2()”. Kotlin no llama a component2() ni crea una variable para este componente. Importante: los guiones bajos solo se pueden usar en declaraciones de desestructuración, no en el constructor de data class. Si se omiten varios componentes consecutivos, cada uno recibe su propio guion bajo.
Para clases sin el modificador data, se puede definir manualmente componentN() agregando la palabra clave operator. Esto permite usar la declaración de desestructuración con cualquier clase, incluidas clases de terceros cuyo código fuente no se puede modificar — simplemente escriba una función de extensión con operator. Este enfoque es especialmente útil para clases de bibliotecas y clases Java que no tienen componentN() automáticos.
class Rect(val width: Int, val height: Int)
operator fun Rect.component1(): Int = width
operator fun Rect.component2(): Int = height
// Para clase Java con getters
operator fun Dimension.component1(): Int = width
operator fun Dimension.component2(): Int = height
fun main() {
val rect = Rect(1920, 1080)
val (w, h) = rect
println("Resolución: ${w}x${h}")
}
En el ejemplo, Rect es una clase normal sin data. Las funciones de extensión con operator fun component1() = width y component2() = height añaden soporte de desestructuración. De manera similar para java.awt.Dimension: una extensión operator sobre Dimension permite descomponerlo en width y height. Limitación: el número máximo de componentes para la declaración de desestructuración es 5. En teoría se puede definir component6() y superiores, pero Kotlin no generará la sintaxis correspondiente para 6+ variables entre paréntesis.
Preguntas frecuentes
Sí, cada data class obtiene automáticamente componentN() para todas las propiedades del constructor primario. Las propiedades declaradas en el cuerpo de la clase (mediante parámetros del constructor sin val/var) no generan componentN().
Si val (a, b, c) = obj tiene un objeto con solo dos funciones component, el compilador mostrará un error. Si hay menos variables (val (a) = pair), Kotlin solo llamará a component1() e ignorará component2() — no ocurrirá ningún error.
Sí, Map.Entry admite desestructuración: val (key, value) = map.entries.first(). La desestructuración no funciona en todo el Map a la vez — solo elemento por elemento, en un bucle for o mediante un iterador.
Sí, Kotlin admite desestructuración en parámetros lambda: map.forEach { (k, v) -> ... }. Para data classes en parámetros lambda, debe agregar paréntesis anidados alrededor del parámetro.
Kotlin admite hasta 5 variables en una declaración de desestructuración. Si necesita descomponer más de cinco propiedades, combínelas en data classes anidadas o use Pair/Triple dentro de una sola variable.
Resumen
val (a, b) = obj, descompone un objeto en varias variables en una sola expresiónDesarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también