Cómo obtener un slice de claves de un map en Go: guía 2025

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿El dolor de cabeza eterno del desarrollador Go? Cómo extraer rápidamente todas las claves de un map.

\n

¿Alguna vez has escrito algo como esto en Go?

\n
m := map[string]int{"go": 1, "python": 2, "rust": 3}\nkeys := make([]string, 0, len(m))\nfor k := range m {\n    keys = append(keys, k)\n}\n
\n

Si es así, no estás solo. Obtener un slice de claves de un map es una de las tareas más populares en Stack Overflow en la categoría de Go. La pregunta acumula miles de visitas y debajo hay decenas de respuestas con diferentes enfoques. Y no es de extrañar: en Go no hay una función incorporada keys() como en Python o JavaScript. Cada vez hay que reinventar la rueda.

\n

Pero 2025 trajo cambios. Con la llegada de Go 1.22 y los genéricos, así como nuevos modismos, han surgido soluciones más elegantes. En este artículo analizaremos todas las formas de obtener un slice de claves de un map, desde lo clásico hasta las mejores prácticas modernas. ¡Allá vamos!

\n\n

¿Por qué Go no tiene un keys() incorporado?

\n

Antes de lanzarnos al código, entendamos la filosofía del lenguaje. Go es minimalista. Sus creadores deliberadamente no añaden funciones que se puedan implementar en una sola línea. for k := range m es la forma incorporada de iterar sobre un map. Pero el problema es que:

\n
    \n
  • El orden de las claves no está garantizado (y es una característica, no un error)
  • \n
  • No hay azúcar sintáctico para "recoge todo en un slice"
  • \n
  • Los genéricos aparecieron solo en 1.18 y se consolidaron hacia 1.22
  • \n
\n

Por eso la comunidad ha desarrollado varios patrones. Vamos a compararlos.

\n\n

Método 1: Bucle clásico (nivel básico)

\n

La forma más simple y comprensible es la que mostramos al principio. Funciona en cualquier versión de Go.

\n
func Keys(m map[string]int) []string {\n    keys := make([]string, 0, len(m))\n    for k := range m {\n        keys = append(keys, k)\n    }\n    return keys\n}\n
\n

Ventajas:

\n
    \n
  • Transparencia: cualquier principiante entenderá lo que sucede
  • \n
  • Sin dependencias de la versión de Go
  • \n
  • Fácilmente modificable (por ejemplo, añadir filtrado)
  • \n
\n

Desventajas:

\n
    \n
  • Mucho código repetitivo para cada map
  • \n
  • Hay que escribir una función separada para cada tipo
  • \n
\n

Veredicto: excelente para ejemplos educativos o tareas puntuales. Pero en código de producción se desea universalidad.

\n\n

Método 2: Genéricos (Go 1.18+)

\n

Con la llegada de los genéricos, surgió la posibilidad de escribir una sola función para cualquier tipo de clave.

\n
func Keys[K comparable, V any](m map[K]V) []K {\n    keys := make([]K, 0, len(m))\n    for k := range m {\n        keys = append(keys, k)\n    }\n    return keys\n}\n\n// Uso:\nm := map[string]int{"a": 1, "b": 2}\nkeys := Keys(m) // []string{"a", "b"}\n
\n

Hermoso, ¿verdad? Una función y todo funciona. Go 1.22 hizo que los genéricos sean aún más estables, por lo que este método es el recomendado para proyectos nuevos.

\n

Importante: las claves deben ser comparable. Esto se cumple automáticamente para todos los tipos estándar (string, int, float, struct sin slices, etc.).

\n\n

Método 3: Uso de reflect (para casos exóticos)

\n

A veces es necesario trabajar con un map cuyo tipo solo se conoce en tiempo de ejecución. Aquí viene al rescate el paquete reflect.

\n
func KeysReflect(m interface{}) []interface{} {\n    v := reflect.ValueOf(m)\n    if v.Kind() != reflect.Map {\n        return nil\n    }\n    keys := make([]interface{}, v.Len())\n    for i, k := range v.MapKeys() {\n        keys[i] = k.Interface()\n    }\n    return keys\n}\n
\n

Cuándo usarlo:

\n
    \n
  • Al serializar/deserializar estructuras desconocidas
  • \n
  • En bibliotecas de propósito general
  • \n
  • Cuando el tipo de map proviene de una fuente externa (JSON, YAML)

Blogs

Book Recommendations