Mascota Jacar — leyendo contigo Un portátil cuyos ojos siguen el cursor mientras lees.
Desarrollo de Software

Go 1.22: novedades que simplifican el código idiomático

Go 1.22: novedades que simplifican el código idiomático

Actualizado: 2026-05-03

Go 1.22 llegó el 6 de febrero de 2024 y corrige dos fricciones que han marcado la experiencia del lenguaje durante casi una década: la semántica de las variables de bucle y la pobreza del enrutador HTTP estándar. A eso se suma una maduración del sistema de toolchain y una colección de mejoras puntuales en la biblioteca estándar. Ninguna novedad reinventa Go, pero el saldo neto es que el código idiomático de 2024 se escribe con menos trampas y menos dependencias externas.

Puntos clave

  • El fix de captura en bucles es el cambio más impactante: desde 1.22, las variables del for se redeclaran en cada iteración cuando el go.mod declara go 1.22. Desaparece el x := x defensivo.
  • net/http.ServeMux ahora soporta método como prefijo de patrón, segmentos con nombre y wildcard — haciendo innecesario gorilla/mux o chi para proyectos sencillos.
  • for i := range 10 es el azúcar sintáctico visible; alinea la escritura con el estilo de rango que ya domina el idioma.
  • La toolchain gestionada (toolchain en go.mod) resuelve la fricción logística de equipos con versiones distintas instaladas.
  • math/rand/v2 con ChaCha8 inaugura el esquema /v2 dentro de la stdlib, la primera ruptura de compatibilidad intencionada.

El final del fallo de captura en bucles

El cambio más relevante es también el menos vistoso. Hasta 1.21, las variables declaradas en la cabecera de un for compartían dirección entre iteraciones. Cualquier closure o goroutine lanzada dentro del bucle capturaba la misma variable, no su valor en ese instante.

El patrón es tan conocido que aparece en casi todos los cursos introductorios como ejemplo de lo que no se debe hacer, y ha sido la causa de una cantidad difícil de estimar de bugs en producción, sobre todo en pipelines concurrentes donde el síntoma es un resultado repetido en vez de un error explícito.

Desde 1.22, si el go.mod declara go 1.22, la variable se redeclara en cada iteración. La propuesta se probó durante todo el ciclo 1.21 tras GOEXPERIMENT=loopvar y el equipo de Go publicó una auditoría del código de Google que confirmó que el cambio resolvía errores reales y apenas rompía nada. La compatibilidad hacia atrás se mantiene porque el comportamiento nuevo solo se activa con la directiva de versión del módulo.

Este es el tipo de arreglo que vale toda la versión. No cambia cómo se escribe el código nuevo, pero elimina una clase entera de bugs latentes en el viejo y quita el asterisco mental que había que poner cada vez que se lanzaba una goroutine dentro de un for.

ServeMux aprende a enrutar

El segundo cambio de peso es net/http.ServeMux. La implementación anterior se limitaba a coincidir por prefijo de ruta, sin distinguir métodos ni soportar parámetros, de modo que cualquier API mínimamente seria tiraba de gorilla/mux, chi o gin casi por inercia.

En 1.22 el multiplexor estándar admite método como prefijo del patrón, segmentos con nombre entre llaves y un comodín {rest...}:

go
mux := http.NewServeMux()
mux.HandleFunc("GET /users/{id}", getUser)
mux.HandleFunc("POST /users", createUser)
mux.HandleFunc("DELETE /users/{id}", deleteUser)

func getUser(w http.ResponseWriter, r *http.Request) {
    id := r.PathValue("id")
    // usar el id capturado
}

Para un servicio REST pequeño o mediano, esto hace innecesario el router externo. Los frameworks siguen aportando valor cuando hay middleware compartido, validación automática o generación de OpenAPI, pero el escalón de entrada para servir una API limpia sin dependencias se ha bajado notablemente. Este patrón encaja bien con microservices en Deno Deploy o con handlers dentro de Linkerd donde la simplicidad del routing reduce la superficie de errores.

Rango sobre enteros y otros retoques de lenguaje

for i := range 10 permite escribir un bucle numérico sin el i := 0; i < n; i++ clásico. No cambia el rendimiento ni la expresividad en el fondo, pero alinea la escritura con el estilo de rango que ya domina el idioma. Es el tipo de cambio que en seis meses se siente natural y en doce ya no se recuerda cómo era antes.

Toolchain: versión del módulo y versión del compilador

Go 1.21 introdujo las directivas go y toolchain en go.mod, y 1.22 termina de afinar su comportamiento:

  • go marca la versión mínima del lenguaje que el módulo asume.
  • toolchain indica qué versión concreta del compilador debe usarse.
  • Si la toolchain declarada no está instalada, go la descarga de forma transparente.

Para equipos donde conviven máquinas con distintas versiones instaladas, o para CI que no siempre está al día, resuelve un problema logístico que hasta hace poco se gestionaba a mano con scripts o con asdf.

La periferia de la biblioteca estándar

Tres cambios merecen atención:

  • math/rand/v2 estrena generador ChaCha8, API más limpia (IntN, Uint64) y rompe compatibilidad de forma consciente manteniendo math/rand intacto. Es el primer paquete que inaugura el esquema de versionado /v2 dentro de la stdlib.
  • log/slog, estabilizado en 1.21, se consolida como el reemplazo natural de log para quien quiera logging estructurado sin depender de zap o zerolog.
  • govulncheck sigue madurando como herramienta oficial para cruzar dependencias contra la base de datos de vulnerabilidades de Go. Es razonable integrarlo ya en CI, en el mismo pipeline donde corren los tests de Semaphore Ansible.

Qué puede romperse al migrar

El cambio de semántica de bucles es el que más atención requiere, aunque en la mayoría de casos los tests lo detectan. Si algún trozo de código dependía intencionadamente de la variable compartida entre iteraciones, habrá que reescribirlo.

ioutil queda deprecado por completo; la migración a os e io es mecánica y gopls la sugiere. Para la mayoría de repos la actualización consiste en instalar la toolchain 1.22, cambiar la directiva go en go.mod, correr go vet ./... y los tests. Una tarde basta salvo casos patológicos.

Conclusión

Go 1.22 confirma la tesis de fondo del lenguaje: los avances llegan despacio, pasan por procesos de prueba largos y respetan la compatibilidad retroactiva de forma casi religiosa. El arreglo de captura en bucles cambia de verdad cómo se escribe Go concurrente. El ServeMux con métodos y parámetros cambia la decisión de qué router usar en proyectos nuevos. La toolchain gestionada cambia cómo se incorpora a alguien nuevo en un proyecto. Actualizar no regala rendimiento espectacular ni sintaxis deslumbrante, pero sí quita dos piedras del zapato que llevaban ahí demasiado tiempo.

¿Te ha resultado útil?
[Total: 14 · Media: 4.2]

Escrito por

CEO - Jacar Systems

Apasionado de la tecnología, la infraestructura cloud y la inteligencia artificial. Escribe sobre DevOps, IA, plataformas y software desde Madrid.