Propiedades Respaldadas Por Mapas

ANUNCIO
Loading...

En este tutorial verás el uso de propiedades respaldadas por mapas. Esta es otra utilidad de las propiedades delegadas, donde usarás mapas como delegados para la lectura y escritura de los valores de tus propiedades.

Delegar A Mapa Inmutable

Para tomar el valor de las propiedades delegadas desde en un mapa, usa la cláusula by en la declaración de la misma, seguido del mapa que actuará como delegado.

val propiedad: Tipo by mapa
Lenguaje del código: Kotlin (kotlin)

La propiedad tomará el valor del par al que corresponde su nombre como clave. Esta lógica se ejecuta dentro de la funciones de extensión Map<K, V>.getValue().

Ejemplo:

Crear el modelo de un jugador de NBA a partir de un mapa con sus datos básicos: primer nombre, apellido, ID de jugador e ID de equipo.

class NbaPlayer(nbaInfo: Map<String, Any?>) { val firstName: String by nbaInfo val lastName: String by nbaInfo val playerId: Int by nbaInfo val teamId: Int by nbaInfo override fun toString(): String { var toPrint = "Nombre: $firstName\n" toPrint += "Apellido: $lastName\n" toPrint += "Id jugador: $playerId\n" toPrint += "Id equipo: $teamId\n" return toPrint } }
Lenguaje del código: Kotlin (kotlin)

La solución anterior declara la clase NbaPlayer con el mapa nbaInfo como parámetro de entrada. Luego definimos 4 propiedades de solo lectura para los datos y se las delegamos al mapa.

Ahora creemos una instancia de NbaPlayer y deleguemos su inicialización a un mapa cuyas claves correspondan a las propiedades:

fun main() { val playerMap = mapOf( "firstName" to "Jaylen", "lastName" to "Adams", "playerId" to 1629121, "teamId" to 1610612749 ) val player1 = NbaPlayer(playerMap) println(player1) }
Lenguaje del código: Kotlin (kotlin)

Salida:

Nombre: Jaylen Apellido: Adams Id jugador: 1629121 Id equipo: 1610612749

Claro está que si el nombre de la clave no coincide con el de la propiedad, tendrás una excepción NoSuchElementException. Y si el tipo de los valores difiere, será una ClassCastException.

Delegar A Mapa Mutable

Claro está que las propiedades mutables deben delegar a instancias de MutableMap para cubrir la modificación de su valor. Esto permitirá dirigir el valor asignado a las propiedades hacia mapa delegado si así lo deseas.

La convención de la delegación es posible, porque MutableMap tiene definido el operador setValue() para confiarle la lógica de los setters en las propiedades delegadas.

Ejemplo:

A partir de un mapa mutable que contiene el perfil de un usuario, inicializar una variable que almacene el nick y lo muestre.

fun main() { val userProfile = loadUserProfile() val displayName by userProfile println("displayName es $displayName") userProfile["displayName"] = "ProtosWin" println("displayName es $displayName") } private fun loadUserProfile() = mutableMapOf( "displayName" to "Killer123", "avatar" to "avatar_22", "language" to "es" )
Lenguaje del código: Kotlin (kotlin)

Salida:

displayName es Killer123 displayName es ProtosWin

En este ejemplo tenemos la variable inmutable local displayName. Variable que delega su valor al mapa userProfile construido a partir de loadUserProfile().

Como puede observar, el valor inicial para la clave "displayName" es "Killer123". Este se entrega a la variable displayName sin problemas, ya que el nombre de la propiedad coincide con la clave.

Luego modificamos el valor por "ProtosWin" e imprimimos de nuevo el valor de displayName corroborando que su valor ha sido modificado, incluso si es val.

Por otro lado, si deseas una modificación bidireccional entre propiedad y mapa, entonces declara la propiedad como var. Al modificarla el mapa también modificará el valor del par asociado.

fun main() { val userProfile = loadUserProfile() // Propiedad var y mapa mutable println("userProfile[\"language\"] -> ${userProfile["language"]}") var language by userProfile language = "en" println("userProfile[\"language\"] -> ${userProfile["language"]}") }
Lenguaje del código: Kotlin (kotlin)

Salida:

userProfile["language"] -> es userProfile["language"] -> en
Lenguaje del código: CSS (css)

Al asignar el valor "en" a language, el valor del par será mutado al nuevo estado como se ve en la impresión.

¿Ha sido útil esta publicación?