Go
Tutorial Go: Mapas
Go Mapas: aprende a crear y manipular mapas en Go. Domina mapas anidados, iteración, eliminación de pares y mejora el rendimiento en estructuras de datos.
Aprende Go GRATIS y certifícateCreación y manipulación de mapas
En Go, los mapas son colecciones desordenadas de pares clave-valor, donde las claves son únicas dentro del mapa. Para crear un mapa, se utiliza la función incorporada make
o mediante la declaración literal de mapas.
Por ejemplo, para crear un mapa que asocia cadenas a enteros:
miMapa := make(map[string]int)
También es posible inicializar un mapa con valores utilizando una declaración literal:
otroMapa := map[string]int{
"clave1": 100,
"clave2": 200,
}
Una vez creado el mapa, se pueden agregar nuevos pares clave-valor asignándolos directamente:
miMapa["nuevaClave"] = 42
Para recorrer un mapa, se utiliza el bucle for range
, que itera sobre las claves y los valores:
for clave, valor := range miMapa {
fmt.Printf("Clave: %s, Valor: %d\n", clave, valor)
}
Es importante mencionar que el orden de iteración en un mapa es aleatorio, ya que los mapas en Go no mantienen un orden específico. Esto significa que cada vez que se recorre un mapa, el orden de los elementos puede variar.
Los mapas pueden ser anidados, permitiendo estructuras más complejas. Por ejemplo, un mapa cuya clave es una cadena y cuyo valor es otro mapa:
mapaAnidado := make(map[string]map[string]int)
mapaAnidado["categoría"] = make(map[string]int)
mapaAnidado["categoría"]["subclave"] = 1
Para mejorar el rendimiento y evitar asignaciones innecesarias, es posible especificar la capacidad inicial del mapa al crearlo:
mapaConCapacidad := make(map[string]int, 100)
Esto inicializa un mapa con una capacidad estimada para 100 elementos, lo que puede ser útil cuando se conoce de antemano el tamaño aproximado del mapa.
Los mapas también pueden interactuar con otras estructuras de datos. Por ejemplo, para convertir un mapa en una lista de claves o valores:
var claves []string
for clave := range miMapa {
claves = append(claves, clave)
}
La comparación directa entre mapas no está permitida en Go. No se pueden comparar dos mapas utilizando el operador ==
, excepto si se compara con nil
. Para verificar si dos mapas son iguales, es necesario comparar sus contenidos de forma manual.
Finalmente, es posible eliminar todos los elementos de un mapa de forma eficiente asignando un nuevo mapa vacío a la misma variable:
miMapa = make(map[string]int)
Esto libera la memoria asociada al mapa anterior y proporciona un mapa vacío para su reutilización.
Acceso y modificación de elementos
Para acceder a un elemento en un mapa, se utiliza la clave entre corchetes después del nombre del mapa. Por ejemplo, si tenemos un mapa miMapa
y queremos obtener el valor asociado a la clave "clave1"
:
valor := miMapa["clave1"]
fmt.Println(valor)
Si la clave no existe en el mapa, se devolverá el valor cero del tipo de los valores del mapa. Por ejemplo, si los valores son enteros, obtendremos 0
.
Para modificar el valor asociado a una clave específica, simplemente se asigna un nuevo valor utilizando la misma sintaxis:
miMapa["clave1"] = 42
Esta operación actualizará el valor de "clave1"
a 42
. Si la clave no existía previamente en el mapa, se creará un nuevo par clave-valor.
Es común querer saber si una clave existe en el mapa antes de realizar alguna acción. Para ello, se emplea el idioma coma, ok:
valor, existe := miMapa["clave2"]
if existe {
fmt.Printf("El valor es %d\n", valor)
} else {
fmt.Println("La clave no existe en el mapa")
}
En este caso, la variable existe
será true
si la clave "clave2"
está presente en el mapa, y false
en caso contrario.
Al trabajar con mapas, es importante tener en cuenta que los valores son referencia directa al mapa original. Esto significa que si se pasa un mapa a una función y se modifica dentro de ella, los cambios serán visibles fuera de la función.
func agregarElemento(m map[string]int, clave string, valor int) {
m[clave] = valor
}
agregarElemento(miMapa, "nuevaClave", 100)
Después de llamar a agregarElemento
, el mapa miMapa
contendrá el nuevo par clave-valor.
Para iterar y acceder a los elementos de un mapa, se utiliza el bucle for range
:
for clave, valor := range miMapa {
fmt.Printf("Clave: %s, Valor: %d\n", clave, valor)
}
Esta estructura permite recorrer todos los pares clave-valor presentes en el mapa.
Si se necesita actualizar todos los valores del mapa basándose en cierta lógica, se puede hacer dentro del bucle:
for clave := range miMapa {
miMapa[clave] *= 2
}
Este código duplica cada uno de los valores asociados a las claves en el mapa.
Es posible también acceder parcialmente a los elementos del mapa. Si solo interesa la clave o el valor, se puede omitir el otro utilizando el identificador de blanco _
:
for _, valor := range miMapa {
fmt.Println(valor)
}
Aquí, solo se imprimen los valores, ignorando las claves.
Cuando se trabaja con mapas cuyos valores son tipos complejos, como estructuras, es crucial recordar que las estructuras se copian por valor. Por lo tanto, para modificar los campos de una estructura almacenada en un mapa, se debe trabajar con punteros o reasignar el valor completo.
type Persona struct {
Nombre string
Edad int
}
mapaPersonas := make(map[string]Persona)
mapaPersonas["ID123"] = Persona{"Alice", 30}
// Intento de modificar la edad (no funcionará)
persona := mapaPersonas["ID123"]
persona.Edad = 31
// La edad sigue siendo 30
fmt.Println(mapaPersonas["ID123"].Edad)
Para que la modificación tenga efecto, se debe reasignar el valor al mapa:
persona := mapaPersonas["ID123"]
persona.Edad = 31
mapaPersonas["ID123"] = persona
Alternativamente, se puede utilizar un mapa de punteros:
mapaPersonasPtr := make(map[string]*Persona)
mapaPersonasPtr["ID123"] = &Persona{"Bob", 25}
// Modificación directa
mapaPersonasPtr["ID123"].Edad = 26
fmt.Println(mapaPersonasPtr["ID123"].Edad)
Al usar punteros, los cambios en los campos de la estructura se reflejan directamente en el mapa.
Detección de claves y eliminación de pares
Al trabajar con mapas en Go, es fundamental saber cómo detectar si una clave existe y cómo eliminar pares clave-valor. Aunque acceder a un valor en un mapa es sencillo, es importante manejar correctamente los casos en los que una clave puede no estar presente.
Para verificar si una clave existe en un mapa, se utiliza la sintaxis de asignación con el segundo valor de retorno. Este método permite diferenciar entre un valor cero y la ausencia de una clave:
valor, existe := miMapa["claveEjemplo"]
if existe {
fmt.Printf("El valor asociado es %v\n", valor)
} else {
fmt.Println("La clave no existe en el mapa")
}
En este caso, existe
es un valor booleano que será true
si la clave "claveEjemplo"
está presente, y false
en caso contrario.
Es relevante destacar que, incluso si el valor asociado a una clave es el valor cero del tipo del mapa, este método permite distinguir entre una clave existente con valor cero y una clave inexistente. Esto es especialmente útil en tipos numéricos o booleanos donde el valor cero puede ser significativo.
Para eliminar un par clave-valor de un mapa, Go proporciona la función incorporada delete
. Esta función toma como argumentos el mapa y la clave que se desea eliminar:
delete(miMapa, "claveEjemplo")
Después de ejecutar esta instrucción, la clave "claveEjemplo"
y su valor asociado ya no estarán presentes en miMapa
.
Si se intenta eliminar una clave que no existe en el mapa, no ocurre ningún error. La función delete
simplemente no hace nada en este caso, lo cual facilita su uso sin necesidad de comprobaciones previas.
La eliminación de pares clave-valor puede ser útil para gestionar la memoria y los recursos cuando se manipulan mapas grandes o de larga duración. Al eliminar entradas innecesarias, se evita el consumo innecesario de memoria y se mantiene el mapa optimizado.
Es posible eliminar múltiples claves en una iteración si se cumplen ciertas condiciones. Por ejemplo, para eliminar todas las claves cuyos valores cumplen un criterio específico:
for clave, valor := range miMapa {
if debeEliminarse(valor) {
delete(miMapa, clave)
}
}
En este fragmento, la función debeEliminarse
determina si un valor cumple con el criterio para ser eliminado.
Es fundamental tener en cuenta que no se debe modificar la longitud de un mapa mientras se está iterando sobre él, excepto mediante la función delete
. Agregar nuevos pares clave-valor dentro de una iteración puede llevar a comportamientos inesperados.
Además, es posible utilizar la detección de claves para implementaciones condicionales. Por ejemplo, se puede establecer un valor predeterminado si una clave no existe:
if _, existe := miMapa["clavePorDefecto"]; !existe {
miMapa["clavePorDefecto"] = valorPredeterminado
}
Este enfoque garantiza que el mapa siempre contenga una clave con un valor válido, evitando comprobaciones posteriores y posibles errores en tiempo de ejecución.
Por último, es importante recordar que los mapas en Go son referencias a estructuras internas. Por lo tanto, pasar un mapa a una función y modificarlo dentro de ella afectará al mapa original. Esto incluye tanto la adición como la eliminación de pares clave-valor.
Ejercicios de esta lección Mapas
Evalúa tus conocimientos de esta lección Mapas con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Cadenas de texto y manipulación
Selectores y mutexes: concurrencia y exclusión
Agenda de contactos por consola
Composición de structs en lugar de herencia
Estructuras de control
Arrays y slices
Control de flujo y estructuras de bucle
Sistema API REST gestión de libros
Métodos con receptores por valor y por puntero
API REST con net/http
Generics
Evaluación Go
Métodos HTTP con net/http
Crear e invocar funciones
Operadores y expresiones
Polimorfismo a través de Interfaces
Manejo explícito de errores
Estructuras structs
Tipos de datos, variables y constantes
Introducción a Go
Canales y comunicación entre Goroutines
Condiciones de carrera
Punteros y referencias
Goroutines y concurrencia básica
Instalación Go primer programa
Errores personalizados y trazabilidad
Estructuras de datos Mapas
Cliente de API OpenWeatherMap clima
Todas las lecciones de Go
Accede a todas las lecciones de Go y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Go
Introducción Y Entorno
Instalación Y Primer Programa De Go
Introducción Y Entorno
Tipos De Datos, Variables Y Constantes
Sintaxis
Operadores Y Expresiones
Sintaxis
Cadenas De Texto Y Manipulación
Sintaxis
Estructuras De Control
Sintaxis
Control De Flujo Y Estructuras De Bucle
Sintaxis
Funciones
Sintaxis
Arrays Y Slices
Estructuras De Datos
Mapas
Estructuras De Datos
Punteros Y Referencias
Estructuras De Datos
Estructuras Structs
Programación Orientada A Objetos
Métodos Con Receptores Por Valor Y Por Puntero
Programación Orientada A Objetos
Polimorfismo A Través De Interfaces
Programación Orientada A Objetos
Composición De Structs En Lugar De Herencia
Programación Orientada A Objetos
Generics
Programación Orientada A Objetos
Manejo Explícito De Errores
Manejo De Errores Y Excepciones
Errores Personalizados Y Trazabilidad
Manejo De Errores Y Excepciones
Métodos Http Con Net/http
Comunicación Por Http
Api Rest Con Net/http
Comunicación Por Http
Goroutines Y Concurrencia Básica
Concurrencia Y Paralelismo
Canales Y Comunicación Entre Goroutines
Concurrencia Y Paralelismo
Condiciones De Carrera
Concurrencia Y Paralelismo
Selectores Y Mutexes Concurrencia Y Exclusión Mutua
Concurrencia Y Paralelismo
Evaluación Conocimientos Go
Evaluación
Certificados de superación de Go
Supera todos los ejercicios de programación del curso de Go y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Crear mapas en Go utilizando
make
y literales de mapa. - Acceder y modificar elementos en mapas.
- Verificar la existencia de claves con el idioma coma, ok.
- Iterar sobre mapas usando bucles
for range
. - Implementar y manipular mapas anidados.
- Eliminar pares clave-valor utilizando la función
delete
. - Optimizar el rendimiento especificando la capacidad inicial de mapas.
- Entender la no comparabilidad directa de mapas.
- Gestionar referencias al pasar mapas a funciones.
- Modificar estructuras almacenadas en mapas y comprender el comportamiento por valor y por referencia.