Maps en Go (Golang)steemCreated with Sketch.

in cervantes •  6 years ago 

gopher wallpaper
En mi publicación anterior conocimos lo que es un array y un slice en el lenguaje de programación Go, en esta ocasión conoceremos lo que es un map, un tipo de dato bastante interesante y versátil.

Maps

Un vector asociativo (también contenedor asociativo, mapa, mapeador, hash, diccionario, mapa finito, tabla de consulta) es un tipo abstracto de dato formado por una colección de claves únicas y una colección de valores, con una asociación uno a uno.
Fuente Wikipedia

Un map es, básicamente, el equivalente a los diccionarios o arreglos asociativos en otros lenguajes de programación, es decir, almacenan parejas de clave y valor. Los valores dentro de estos pueden ser obtenidos o actualizados de manera semejante a como lo hacemos en un array o slice, solo que el indice no está limitado a un número entero y los valores no se encuentran ordenados. Veamos como declarar un map.

var mapaUno map[string]int
mapaUno = make(map[string]int)
mapaUno["uno"] = 1
mapaUno["dos"] = 2
fmt.Println("mapaUno:", mapaUno) // mapaUno: map[uno:1 dos:2]

mapaDos := make(map[string]int)
mapaDos["uno"] = 1
mapaDos["dos"] = 2
fmt.Println("mapaDos:", mapaDos) // mapaDos: map[uno:1 dos:2]

mapaTres := map[string]int{"uno": 1, "dos": 2}
fmt.Println("mapaTres:", mapaTres) // mapaTres: map[uno:1 dos:2]



En los tres casos anteriores obtenemos el mismo resultado, un map que contiene dos parejas clave-valor. Es importante mencionar, que en la primera declaración creamos un mapa con valor nil; en ese caso, si intentamos agregar un nuevo valor obtendremos un error, por ese motivo asignamos un map vacío haciendo uso de la función make. Por lo que notarán que no hay mucha diferencia entre las variables mapaUno y mapaDos, simplemente nos ahorramos una linea gracias a la declaración corta. En el caso de mapaTres usamos una asignación literal, pasando entre llaves los pares clave-valor. Ahora veamos algunas operaciones con mapas.

Agregando valores a un Map

mapa := map[string]int{"uno": 1, "dos": 2}
fmt.Println("mapa:", mapa) // mapa: map[uno:1 dos:2]

mapa["tres"] = 3
mapa["cuatro"] = 4
fmt.Println("mapa:", mapa)   // mapa: map[uno:1 dos:2 tres:3 cuatro:4]
fmt.Println("El valor tres es:", mapa["tres"]) // El valor tres es: 3

fmt.Println("El valor cinco es:", mapa["cinco"])  // El valor cinco es: 0



Añadir nuevos valores al arreglo no suponen ninguna dificultad, tampoco acceder a un valor previamente almacenado, por medio de la notación de corchetes, usando la clave correspondiente tenemos acceso al valor. De igual forma, intentar acceder a un elemento por medio de una clave que no se encuentre presente en el mapa retorna el valor cero del tipo declarado en el mapa, siendo int en este caso, el resultado de llamar al valor con la clave cinco es 0.

Modificando valores de un Map

mapa := map[string]int{"uno": 1, "dos": 2, "tres": 3, "cuatro": 4}
fmt.Println("mapa:", mapa) // mapa: map[uno:1 dos:2 tres:3 cuatro:4]

mapa["tres"] = 8
mapa["cuatro"] = 16
fmt.Println("mapa:", mapa) // mapa: map[uno:1 dos:2 tres:8 cuatro:16]



No creo que requiera mayor explicación, con la misma notación de corchetes con la que accedemos y agregamos valores podemos modificar valores. Ahora veamos como borrarlos.

mapa := map[string]int{"uno": 1, "dos": 2, "tres": 3, "cuatro": 4}
fmt.Println("mapa:", mapa) // mapa: map[uno:1 dos:2 tres:3 cuatro:4]
delete(mapa, "tres")
fmt.Println("mapa:", mapa) // mapa: map[uno:1 dos:2 cuatro:4]



La función delete nos permite fácilmente eliminar elementos de un map, sólo debemos pasar como primer argumento el map y como segundo la clave correspondiente.

Más sobre los Maps

Es posible que surgieran algunas preguntas durante la lectura de las secciones anteriores, a mi me surgieron y me tocó investigar un poco, así que se los voy a compartir.

¿Puedo comprobar si un elemento se encuentra en el Mapa antes de acceder a él?

La respuesta es sí. Como dije anteriormente, si intentamos acceder a un valor del mapa con una clave que no esta presente en el mismo obtendremos el valor cero del tipo correspondiente, esto podría dar origen a errores difíciles de detectar dependiendo del caso, por lo que resulta útil poder comprobar si se encuentra o no en mapa antes de realizar alguna operación con él.

mapa := map[string]int{"uno": 1, "dos": 2, "tres": 3, "cuatro": 4}

if el, ok := mapa["cinco"]; ok {
    fmt.Println("El valor de cinco es:", el)
}



Debido a que la clave cinco no se encuentra presente en mapa, el valor de la variable ok es false, por lo tanto, la variable el (que almacena el valor correspondiente a la clave) no llega a imprimirse.

¿Sólo puedo almacenar valores de un tipo en un Mapa?

Como sabemos, el lenguaje Go es de tipado estático, por lo que la respuesta podría ser no, pero existe una forma, la conocí gracias al profesor Alexys Lozada de la comunidad Go en Español y es mediante el uso de interfaces. Aún no he tocado las interfaces en esta serie de publicaciones, pero prometo hacerlo pronto; por el momento pueden consideralas como otro tipo de dato y observar el siguiente ejemplo.

mapa := make(map[string]interface{})

mapa["primero"] = 4
mapa["segundo"] = false
mapa["tercero"] = "Steemit"

fmt.Println(mapa)  // map[segundo:false tercero:Steemit primero:4]


Mapas literales multilinea

Esto no es realmente una duda, más bien algo que me pareció útil porque hasta el momento solo he realizado declaraciones de una linea y puede volverse difícil de leer.

tareasPendientes := map[string]string{
    "primero": "Realizar post de punteros en Go",
    "segundo": "Continuar el tutorial práctico de Echo",
    "tercero": "Realizar post de interfaces en Go",
}



La coma al final del último elemento es obligatoria, a menos que se deje la llave de cierre al mismo nivel del último elemento, pero me gusta más la forma que les dejo en el ejemplo. Son libres de usar la que más les guste.

Recorrer mapas con un ciclo

Como deben saber si han estado siguiendo mis publicaciones anteriores, existen distintas variaciones del ciclo for, me limitaré a mostrar la manera natural de recorrer un map, es decir, el for-range.

package main

import (
    "fmt"
)

func main() {
    tareasPendientes := map[string]string{
        "primero": "Realizar post de punteros en Go",
        "segundo": "Continuar el tutorial práctico de Echo",
        "tercero": "Realizar post de interfaces en Go",
    }
    for k, v := range tareasPendientes {
        fmt.Println(k, "=>", v)
    }
}



No les compartiré la salida de ese código, los invito a probarlo ustedes mismos, por tal motivo lo coloqué completo. Si no quieren instalar aún el compilador de Go pueden usar este playground, de cualquier forma, hagan pruebas, realicen modificaciones y no duden en compartir sus experiencias o problemas.

separator.png

Publicaciones relacionadas

  1. De Python a Go (Golang)

  2. Introducción al lenguaje de programación Go (Golang)

  3. Estructuras de control de flujo en Go

  4. Array y Slice en Go (Golang)

Gracias por leer, espero que este articulo te resultara de provecho. Si así fue, no dudes en dejar un comentario, compartirlo y votar. Te invito a comentar cualquier duda o sugerencia, te aseguro que las leo todas. Así que, por favor, ayúdame a mejorar y continuar compartiendo contenido de calidad. Hasta la próxima.

banner-steemit.jpg

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Hello! Your post has been resteemed and upvoted by @ilovecoding because we love coding! Keep up good work! Consider upvoting this comment to support the @ilovecoding and increase your future rewards! ^_^ Steem On!

Reply !stop to disable the comment. Thanks!

@orlmicron, I gave you a vote!
If you follow me, I will also follow you in return!
Enjoy some !popcorn courtesy of @nextgencrypto!

Este post fue votado por la comunidad y trail @developspanish, comunidad encargada de curar a los programadores, traductores de software y bloggers de informática y tecnología de habla hispana.

¿Quieres recibir mejores recompensas en tus post de informática, tecnología o programación, ayúdanos delegando algo de SP:
1 SP, 5 SP, 10 SP

Congratulations @orlmicron! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

Award for the number of posts published

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

SteemitBoard - Witness Update
SteemFest³ - SteemitBoard support the Travel Reimbursement Fund.

Support SteemitBoard's project! Vote for its witness and get one more award!

Congratulations @orlmicron! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You got your First payout

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

SteemitBoard - Witness Update

Support SteemitBoard's project! Vote for its witness and get one more award!