Go 1.22 was released on February 7th, 2024. It's a major release with some significant quality-of-life improvements over Go 1.21. Let's go through them!

Everything you need to know about Go 1.22


Just six months after Go 1.21 was released, here we are again! The Go team and community really do work hard!

The Go 1.22 release introduces several changes across the language, tools, runtime, compiler, and standard library.

Let’s look at each of these areas. This overview is not intended to be exhaustive; it highlights key changes. For more details, check the official release notes.

If you prefer to learn by watching, I created a free course called Go 1.22 in 22 minutes, which covers all the major changes too.

Language Changes

For Loops Enhancements: Variables declared in a for loop are now created anew for each iteration, preventing accidental sharing bugs. Additionally, for loops can now range over integers, and there’s a preview of range-over-function iterators enabled with GOEXPERIMENT=rangefunc.

Here’s an example of the for loop changes:

package main

import "fmt"

func main() {
    for i := range 11 {
    fmt.Println(11 - i)
    }
    fmt.Println("go1.22 just shipped!")
}

I go through this in more detail in the course here.

New math/rand/v2 Package: Introduces a more efficient and potentially faster random number generation with modern algorithms like ChaCha8 and PCG.

New go/version Package: Implements functions for validating and comparing Go version strings.

HTTP Routing Enhancements: More expressive routing patterns in the standard library, including method restrictions and wildcards.

Here’s an example:

package main

import (
"fmt"
"net/http"
)

func main() {
    mux := http.NewServeMux()

    mux.HandleFunc("GET /path/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "got path\n")
    })

    mux.HandleFunc("/game/{id}/", func(w http.ResponseWriter, r *http.Request) {
        articleID := r.PathValue("id")
        fmt.Fprintf(w, "reading game with id=%v\n", articleID)
    })

    http.ListenAndServe("localhost:8080", mux)
}

There are more examples of this in my free course here.

Tools

  • Go Command Improvements: The go command now supports using a vendor directory for dependencies within workspaces. The go get command is deprecated outside module-aware mode. Improvements to go test -cover now include coverage summaries for packages without their own test files.

  • Trace Tool UI Refresh: The trace tool’s web UI has been updated for better usability, including a thread-oriented view and displaying the full duration of all system calls.

  • Vet Tool Updates: Adjustments include new semantics for loop variables, warnings for missing values in append, incorrect defer usage with time.Since, and mismatches in key-value pairs for logging calls.

Runtime

  • Garbage Collection Metadata Optimization: Improves CPU performance and memory overhead by keeping metadata closer to each heap object. This may affect alignment for some objects, with a workaround available through GOEXPERIMENT=noallocheaders.

  • Enhancements for Windows/amd64: Improved support for catching exceptions not handled by the Go runtime.

Compiler

  • Profile-guided Optimization (PGO): Offers significant performance improvements by enabling more devirtualization of calls.

  • Inlining Enhancements: Better optimization of interface method calls through interleaved devirtualization and inlining.

Minor Changes and Performance Improvements

Various minor adjustments and enhancements across the standard library (e.g., archive/tar, archive/zip, crypto/tls, net/http, runtime/metrics) are made with compatibility in mind. Performance improvements are also part of this release but not detailed extensively.

I hope you found this helpful and find the changes in Go 1.22 positive!