mapstructure en Go: guía completa para mapear map a estructuras
¿Qué es y para qué sirve?
La librería mapstructure para el lenguaje Go resuelve una de las tareas más comunes al trabajar con datos dinámicos: convertir map[string]interface{} sin estructura en estructuras Go fuertemente tipadas. En proyectos reales, los datos suelen llegar en formato JSON, YAML, TOML o desde APIs externas, donde la estructura puede no estar garantizada. El estándar encoding/json funciona bien con JSON, pero cuando trabajas con map arbitrarios (por ejemplo, de archivos de configuración, Redis Hash o resultados de consultas SQL), necesitas una herramienta que pueda mapear datos de forma flexible y segura.
La función principal de mapstructure es tomar un map[strings]interfaces y llenar los campos de una estructura, convirtiendo tipos automáticamente, soportando estructuras anidadas, slices, punteros e incluso tipos personalizados. La librería es especialmente útil al analizar configuraciones, donde las claves pueden estar en snake_case y los campos de la estructura en CamelCase, o cuando necesitas deserializar datos de fuentes que no soportan el esquema JSON estándar.
La ventaja clave de mapstructure frente al mapeo manual es su carácter declarativo. Tú describes la estructura con etiquetas (tags) y la librería se encarga del recorrido recursivo, la conversión de tipos (por ejemplo, de string a int), el manejo de campos opcionales y los errores de incompatibilidad de tipos. Esto hace que el código sea más limpio, seguro y reduce significativamente la cantidad de código repetitivo (boilerplate).
Instalación
Para instalar la librería, usa el gestor de paquetes estándar de Go. Asegúrate de tener un módulo inicializado (go mod init).
go get github.com/mitchellh/mapstructure
Después de ejecutar el comando, la librería se agregará a go.mod y go.sum. Impórtala en tu código:
import "github.com/mitchellh/mapstructure"
La versión al momento de escribir este artículo es la v1.5.0. La librería no tiene dependencias externas, solo la biblioteca estándar de Go.
Inicio rápido — ejemplo mínimo funcional
Creemos una estructura Person simple y convirtamos un map[string]interface{} en una instancia de esa estructura.
package main
import (
"fmt"
"github.com/mitchellh/mapstructure"
)
type Person struct {
Name string
Age int
City string
}
func main() {
input := map[string]interface{}{
"name": "Alice",
"age": 30,
"city": "New York",
}
var person Person
err := mapstructure.Decode(input, &person)
if err != nil {
panic(err)
}
fmt.Printf("Person: %+v\n", person)
// Salida: Person: {Name:Alice Age:30 City:New York}
}
Como puedes ver, las claves del map se asignaron automáticamente a los campos de la estructura (no distingue entre mayúsculas y minúsculas por defecto). Si la clave se llamara "AGE", igualmente se asignaría al campo Age.
Métodos y funciones principales
Veamos las 8 funciones/métodos clave de la librería mapstructure. Cada método incluye su firma, descripción y un ejemplo de código.
1. Decode
Firma: func Decode(input interface{}, output interface{}) error
Qué hace: Es la función principal para decodificar un map en una estructura. Acepta cualquier input (generalmente map[string]interface{}) y un puntero a la estructura de salida. Devuelve un error si los tipos son incompatibles o surge algún otro problema.
type Config struct {
Host string
Port int
}
func main() {
data := map[string]interface{}{
"host": "localhost",
"port": 8080,
}
var cfg Config
if err := mapstructure.Decode(data, &cfg); err != nil {
panic(err)
}
fmt.Printf("Config: %+v\n", cfg)
// Salida: Config: {Host:localhost Port:8080}
}
También en la biblioteca
Generador de códigos QR en Swift: biblioteca EFQRCode para iOS y macOS
Trabajo con Excel en Swift en iOS y macOS: bibliotecas y ejemplos
Serialización de objetos en Rust: serde, bincode, JSON y YAML
RxJava para Java: guía completa con ejemplos prácticos