Blog
Tech4 min read

Go 1.22 Recap: Loop Variables Fixed, Smarter Routing

The goroutine-in-a-loop bug is gone, net/http routes by method and wildcard, and math/rand gets a v2. Everything that matters in Go 1.22, in five minutes.

#golang #go-recap #backend

Go recap series — one short post per release. Released February 2024.

TL;DR

  • Each loop iteration now gets its own variable.
  • for i := range 10 works.
  • http.ServeMux supports methods and wildcards like GET /items/{id}.
  • New math/rand/v2, slices.Concat, and cmp.Or.
  • PGO makes most programs 2–14% faster.

1. Loop variables are per-iteration

What changed: before 1.22, the whole loop shared one variable. Now every iteration gets a new one.

go
for _, v := range values {
    go func() {
        fmt.Println(v) // 1.22+: prints each value, not the last one N times
    }()
}

Why it matters: the most common Go bug is gone. Delete your v := v workarounds.

2. Range over integers

go
for i := range 10 {
    fmt.Println(i) // 0 to 9
}

Why it matters: less noise than for i := 0; i < 10; i++.

3. Routing with methods and wildcards

What changed: http.ServeMux patterns can include a method and {wildcards}.

go
mux := http.NewServeMux()

mux.HandleFunc("POST /items", createItem)
mux.HandleFunc("GET /items/{id}", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "item", r.PathValue("id"))
})
mux.HandleFunc("GET /files/{path...}", serveFile) // matches the rest of the path
mux.HandleFunc("/{$}", home)                       // matches "/" only

When two patterns match, the more specific one wins. Registering GET also handles HEAD.

Why it matters: for many APIs you no longer need a third-party router.

4. Small but useful

  • math/rand/v2 — cleaner API: rand.IntN(10), rand.N(5*time.Minute).
  • slices.Concat(a, b, c) — join slices in one call.
  • cmp.Or — first non-zero value. Great for defaults:
go
port := cmp.Or(os.Getenv("PORT"), "8080")

5. Faster with PGO

Profile-guided optimization now devirtualizes more calls. The Go team measured 2–14% faster runtime on most programs.

How to use it: save a CPU profile as default.pgo in your main package, then go build.


Next: Go 1.23 Recap →

Source: Go 1.22 release notes

Share To Friends