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
forse redeclaran en cada iteración cuando elgo.moddeclarago 1.22. Desaparece elx := xdefensivo. net/http.ServeMuxahora 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 10es el azúcar sintáctico visible; alinea la escritura con el estilo de rango que ya domina el idioma.- La toolchain gestionada (
toolchainengo.mod) resuelve la fricción logística de equipos con versiones distintas instaladas. math/rand/v2con ChaCha8 inaugura el esquema/v2dentro 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...}:
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:
gomarca la versión mínima del lenguaje que el módulo asume.toolchainindica qué versión concreta del compilador debe usarse.- Si la toolchain declarada no está instalada,
gola 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/v2estrena generador ChaCha8, API más limpia (IntN,Uint64) y rompe compatibilidad de forma consciente manteniendomath/randintacto. Es el primer paquete que inaugura el esquema de versionado/v2dentro de la stdlib.log/slog, estabilizado en 1.21, se consolida como el reemplazo natural delogpara quien quiera logging estructurado sin depender de zap o zerolog.govulnchecksigue 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.