Release of Go v1.24 will bring a lot of features. Let us divide them into three parts (as inspired by The Good, the Bad and the Ugly).

Go 1.24 now requires Go 1.22.6 or later for bootstrap.

This time a pretty long list of changes is included. I will pick those that hit my eyes. The rest automatically falls under The Do-not-care part.


The Useful

Generic type aliases might be defined as simply as type Set[T comparable] = map[K]struct{}. It can be disabled by GOEXPERIMENT=noaliastypeparams.

One might e.g. re-export generic types from internally used packages.

Go module tool support including a separate tool directive in go.mod file. To manage tools one might use:

  • go get -tool github.com/awalterschulze/goderive to add tool to your current Go module;
  • go tool goderive to run the tool;
  • go get tool to update all tools (perhaps flag -u is needed, not sure right now…);
  • go install tool to install tool into GOBIN;
  • go tool to list all available tools.

Super-convenient feature for those who needs to use tooling (e.g. for equal method generator or for GraphQL schema-based generators, etc.). So one might expect in go.mod something like:

tool (
  golang.org/x/tools/cmd/stringer
  github.com/awalterschulze/goderive
)

Go build cache handles executables built by go run and go tool commands.

Good for a performance and your SSD.

JSON output support for easier automation of processes using tools like go build -json, go install -json, and go test -json.

CI/CD pipelines made easier.

Encoding into JSON now supports brand-new omitzero tag option using IsZero() bool to determine whether the value is zero (to decide whether it shall be omitted or not). One might use both omitempty,omitzero and both checks will be done. Also, UnmarshalTypeError.Field includes embedded structs with detailed error message.

omitzero omits zero value of type time.Time (while omitempty outputs "0001-01-01T00:00:00Z"). And extra context of marshaling error might also be considered useful.

New experimental testing/synctest for concurrent code testing (might be enabled by GOEXPERIMENT=synctest).

  • The synctest.Run function starts a group of goroutines in an isolated “bubble”. Within the bubble, time package functions operate on a fake clock.
  • The synctest.Wait function waits for all goroutines in the current bubble to block.

Easier testing of not just timeouts.

The testing package provides Context method (to detect test being finished) and Chdir method (to change working directory for the test) provided for both T and B types.

Unit tests might be a bit better…

New standard iterators provided by both bytes and strings packages:

  • Lines returns an iterator over the newline-terminated lines in a byte slice.
  • SplitSeq returns an iterator over all sub-slices of a byte slice split around a separator.
  • SplitAfterSeq returns an iterator over sub-slices of a byte slice split after each instance of a separator.
  • FieldsSeq returns an iterator over sub-slices of a byte slice split around runs of whitespace characters, as defined by unicode.IsSpace.
  • FieldsFuncSeq returns an iterator over sub-slices of a byte slice split around runs of Unicode code points satisfying a predicate. But also methods returning iterators for all go/types data structures exposing sequences via Len and At methods.

Imagine all the happy developers using strings.Lines or bytes.Lines. Implementation of own iterators is not that fun, but using them makes the code nice and lean.

The brand-new Text function from crypto/rand can be used to generate cryptographically secure random text strings. Other than that, no more crashing on Read function.

Random string might be of use from day to day.


The Perhaps-important

The go build command sets main module’s version based on the version control system tag or commit. Uncommited changes will include +dirty suffix. Use -buildvcs=false flag to disable this feature.

I have never checked details packed to binaries during compilation. One should check it…

New analyzers reports common mistakes in declaration of tests, fuzzers, benchmarks, examples, and fmt.Printf(s) (where s is a non-constant format string while no other arguments are passed).

Easier detection of mistakes is always appreciated.

Builtin map implementation switched to the one based on Swiss Tables. It can be disabled by GOEXPERIMENT=noswissmap. Also sync.Map is implemented based on Hash Trie. It can be disabled by GOEXPERIMENT=nosynchashtriemap. New runtime internal mutex implementation can be disabled by GOEXPERIMENT=nospinbitmutex.

A bunch of runtime optimizations. One might check more details on Swiss Table and Hash Trie data structures for perhaps interested details.

The new os.Root type (returned by os.OpenRoot()) provides the ability to perform filesystem operations within a specific directory (outside might be reached only via symlinks).

It might be good to investigate os.Root for some hobby tools.

New interfaces TextAppender and BinaryAppender for encoding package to append the textual or binary representation of an object to a byte slice without allocating a new slice each time (in comparison to TextMarshaler and BinaryMarshaler). Those interfaces are implemented by many standard types including those from package math/big, net, regexp, time, crypto, etc.

Easy-gained performance boost by reducing need of memory allocations.

Transport and Server now have HTTP2 fields to enable configuration of HTTP/2 protocol settings.

One might need to fine-tune HTTP/2 protocol.

The go:wasmexport compiler directive is added for Go programs to export functions to the WebAssembly host.

Possibility for an easy way to start messing around with WebAssembly.


The Do-not-care (at least now)

Cgo supports #cgo noescape cFunctionName and #cgo nocallback cFunctionName annotations to improve runtime performance.

Not directly useful as I do not use Cgo anywhere right now.

Benchmark can use introduced b.Loop() { ... }.

There is already pretty nice and concise for range b.N { ... }. Perhaps I did not get two significant advantages:

  • The benchmark function will execute exactly once per -count, so expensive setup and cleanup steps execute only once.
  • Function call parameters and results are kept alive, preventing the compiler from fully optimizing away the loop body.

Improved finalizers.

Too low-level for me now.

Weak pointers as a brand-new low-level primitive provided by weak package.

Perhaps they might enable some memoization…

New crypto algorithms: crypto/mlkem (ML-KEM-768 and ML-KEM-1024; a post-quantum key exchange mechanism formerly known as Kyber and specified in FIPS 203); crypto/hkdf (HMAC-based Extract-and-Expand key derivation function HKDF; RFC 5869); crypto/pbkdf2 (implements the password-based key derivation function PBKDF2; RFC 8018); crypto/sha3 (SHA-3 hash function and SHAKE and cSHAKE extendable-output functions; FIPS 202). But also other topics touched, e.g. new stuff for crypto/rsa, implementation of encoding.BinaryAppender interface by almost every crypto type, and revised certificate handling by crypto/x509.

When you need it, it is great to have it available. If not, you simply skip it…


<
Previous Post
XCompose
>
Next Post
Go v1.23 and older releases