Historia de la pregunta:
En Go no hay contenedores universales del tipo mapa genérico por defecto: solo a partir de Go 1.18 aparecieron las generics, pero para estructuras dinámicas, antes y ahora, se usa frecuentemente map[string]interface{}, lo que permite almacenar valores de cualquier tipo con una clave de cadena.
Problema:
Este patrón es análogo a un diccionario/objeto JSON, se encuentra en todas partes para la serialización, trabajo con middleware, y datos sin una estructura definida (por ejemplo, un analizador JSON a través de encoding/json). Sin embargo, acceder a los valores requiere conversión manual de tipos y precaución con valores nulos y la ausencia de claves.
Solución:
Usar map[string]interface{} donde no se conoce la estructura de los datos de entrada. Comprobar cuidadosamente la existencia de la clave, convertir el tipo (type assertion) solo después de el exists-idiom. Es mejor no mantener tales mapas "profundamente" en la lógica de negocio, sino como adaptadores en los bordes del sistema.
Ejemplo de código:
obj := map[string]interface{}{ "int": 42, "str": "hola", "flag": true, } if v, ok := obj["int"]; ok { n, success := v.(int) if success { fmt.Println(n) } }
Características clave:
¿Se puede acceder sin errores al valor por clave en map[string]interface{} si la clave no existe?
No, esto dará el "cero value" (nil) para interface{}, la conversión de tipo a un tipo específico generará pánico.
¿Qué ocurre al serializar map[string]interface{} con slices anidados u otros mapas?
La serialización JSON procesará correctamente la estructura, pero si hay tipos que no son soportados por defecto (canales, funciones) habrá un error de marshaling.
¿Se pueden comparar dos valores en map[string]interface{} con ==?
No, interface{} solo se puede comparar si el valor subyacente es comparable. Si se incluye un mapa o un slice, habrá pánico al comparar.
En la aplicación toda la lógica se basa en objetos map[string]interface{}, cada controlador/servicio los pasa profundamente a través de las llamadas.
Ventajas:
Desventajas:
Se utilizan map[string]interface{} solo para trabajar con interfaces externas, datos de entrada/salida, y luego se traducen a estructuras normales.
Ventajas:
Desventajas: