- Most information was taken from the [release notes]. - Release is schedules for February 2023. Releases happened between [16th and 25th in the past](https://go.dev/doc/devel/release), so I assume that 1.20 will be released end of February as well. --- ## Context Package `context` received [`WithCancelCause`](https://go.dev/pkg/context/#WithCancelCause) which allows to cancel a context with a given error. This is pretty nice to have something more meaningful than the usual `context.Canceled` error, that won't tell you anything about why something got canceled. ([playground](https://go.dev/play/p/dp-sJNfYp-Y)) ## Errors Support for **wrapping multiple errors**: - [`errors.Join`](https://pkg.go.dev/errors@go1.20rc3#Join) to wrap multiple errors into one (error messages will be newline delimited) - `fmt.Errorf` now also supports multiple `%w` format verbs - ([playground](https://go.dev/play/p/xSsD6AF_w0p)) ## HTTP Response Controller [**`http.ResponseController`** ](https://pkg.go.dev/net/http@go1.20rc3#ResponseController) wraps an `http.ResponseWriter` and makes it more convenient to configure it in a Handler, e.g. no need to make checked-cast to an `http.Hijacker` anymore, just call `responseController.Hijack()`. You can also easily overwrite [read](https://github.com/golang/go/blob/7f59bea53c888605faaa46cd95aaa3ddf29219bf/src/net/http/responsecontroller.go#L84-L96) and [write deadlines](https://github.com/golang/go/blob/7f59bea53c888605faaa46cd95aaa3ddf29219bf/src/net/http/responsecontroller.go#L104-L116) using the response controller. ## Language Changes **Slice to array conversions** are now a bit easier to write ([playground](https://go.dev/play/p/fVXMR6m6ihu?v=gotip)). ```go x := []int{1, 2, 3, 4} var y [4]int // Go 1.17+ // y = *(*[4]int)(x) y = [4]int(x) ``` Note that this will - copy the elements from the slice to the array - conversion from array to slice works the same way - array to slice conversion will run-time panic if the target slice won't fit the array (len(slice) < len(array)) Three new functions for **unsafe modification fo slices**, [`SliceData`, `String`, `StringData`](https://tip.golang.org/ref/spec/#Package_unsafe). Don't use it, except you know what you're doing. The **language specification** now defines that - struct values are compared one field at a time, in the order fields were declared in the struct definition - [array values are compared one element at a time](https://go.dev/play/p/ovlSPbbcIrY), in increasing index order - Note that slices still cannot be checked for equality using the `==` operator! - comparisons stop at the first mismatch This will have no effect on existing programs, just a clear description in the spec what was already implemented The **`comparable` constraint** is now satisfied by [comparable types](https://tip.golang.org/ref/spec#Comparison_operators), sound obvious, right 😅? In practice this means that a `comparable` constrained type parameter can be instantiated with non-strictly comparable types, like `interface`s. As an example, you can do the following from Go 1.20 ([playground](https://go.dev/play/p/lVBUwYionqs?v=gotip)): ```go func f[K comparable, V any](keys []K, values []V) map[K]V { m := make(map[K]V, len(keys)) for idx, key := range keys { m[key] = values[idx] } return m } ``` ## Tools - **Go distribution will become a bit smaller** because pre-compiled packages from the standard library are removed. Instead, packages of the standard library will be compiled on the fly and then stored in the build cache (like any other package). - `go test -json` will **emit a start `Action`** at the beginning of each test execution. - The `go` command received a `-C` flag, to **change working directory**. - Build related commands, `go build` and `go install`, received a `-cover` flag to **build with code coverage instrumentation**. _There will be a separate talk today, that is going to cover this topic in detail._ - **`net` and `os/user` packages are now pure Go packages under macOS**, i.e. they don't require `cgo` anymore. - **`cgo` is not required anymore for the race-detector under macOS** (you can run those tests now without having XCode installed) ## Runtime - Experimental support for arena allocations ([language proposal](https://github.com/golang/go/issues/51317)). Allocations from the memory arena are not considered by the GC and the arena will be freed manually all at once. ([package docs](https://docs.go101.org/std/pkg/arena.html)). Should be handled with care due to easy to introduce use-after-free bugs. - Up to 2% less CPU usage, due to GC improvements. ## Compiler - Support for [PGO], **profile guided optimization**, in builds. This means that the compiler can leverage run-time profile data to optimize the compiled code, e.g. by more aggressive inlining. Claimed performane improvement are about 3-4%. More PGO optimizations will be added in further releases. - Record a CPU profile and pass that to the compiler. - **Up to 10% faster build speeds**, which brings compile times down to pre-generic levels. - There's a Go blog post with more details: <https://go.dev/blog/pgo-preview> ## Standard Library - **New `crypto/ecdh` and `crypto/ecdsa` packages** which replaces the more low-level `crypto/elliptic`. Fillipo Valsorda wrote a deep-dive on the [Go 1.20 crypto changes](https://words.filippo.io/dispatches/go-1-20-cryptography/), e.g. the elliptic curve crypto packages don't rely on `math/big` anymore, which makes them constant time. - [**ReverseProxy Rewrite hook**](https://pkg.go.dev/net/http/httputil@go1.20rc3#ReverseProxy) superceeds `httputil.Director` and now receives in- and outbound requests with its `*httputil.ProxyRequest` argument (unlike a Director function which just received an outbound request). ### Minor standard library changes - `archive/tar` and `archive/zip` return [`ErrInsecurePath`](https://go.dev/pkg/archive/zip/#ErrInsecurePath) if an entry has an absolute path, contains invalid characters etc. Note that this is currently behind a feature flag, `GODEBUG=zipinsecurepath=0` but might get the default in a future release. - the `bytes` package received - [`Clone`](https://github.com/golang/go/blob/518889b35cb07f3e71963f2ccfc0f96ee26a51ce/src/bytes/bytes.go#L1352-L1360), which basically returns a clone of the given byte slice. This is a useful utitlity with a pretty minimal implementation. - `TrimPrefix` and `TrimSuffix` got siblings, called `CutPrefix` and `CutSuffix`. The difference is that the `Cut` functions will return if something was removed or not. - `crypto/tls` TLS certificates are now shared across all clients using a certificate, which might lead to significantly less memory usage. If a handshake fails a new [`CertificateVerificationError`](https://go.dev/pkg/crypto/tls/#CertificateVerificationError ) is returned. - [`io.OffsetWriter`](https://pkg.go.dev/io#OffsetWriter) basically wraps an `io.WriterAt` and adds a given fixed offset to each Seek, Write etc. call. - Directory trees are usually traversed using `fs.Walk`. There's a new `SkipAll` error that can be used to immediately stop the recursion of `fs.Walk`, but this error will be consumed and the call will end successfully. This is mostly for convenience, since you could have achieved the same before, just that the caller had to filter out the custom error that indicates the traversal stop. - `math/rand` will [automatically seed the global RNG](https://github.com/golang/go/blob/518889b35cb07f3e71963f2ccfc0f96ee26a51ce/src/math/rand/rand.go#L323-L334), this can deactivated with `GODEBUG=randautoseed=0`. I'd argue against using the global RNG and to always instantiate a local instance. The same applies to any other global instance. - We got three new time formats: - `DateTime = "2006-01-02 15:04:05"` - `DateOnly = "2006-01-02"` - `TimeOnly = "15:04:05"` - `testing.B` can now report the [elapsed time](https://go.dev/pkg/testing/#B.Elapsed) ### Future - There's a [proposal](https://github.com/golang/go/issues/56345) to add structured logging support to the standard library with package [`log/slog`](https://go.googlesource.com/proposal/+/master/design/56345-structured-logging.md) - Can be used already by importing [`golang.org/x/exp/slog`](https://pkg.go.dev/golang.org/x/exp/slog) - Currently - we only have package [`log`](https://pkg.go.dev/log), a simple logger that has no support for levels etc. - every logging library needs to define their own `Logger` interface - At a high level `slog` is build from three parts: - [Logger](https://pkg.go.dev/golang.org/x/exp/slog#Logger) is user-facing part of the API, exposing methods like `.Info()` or `.Error()`. > A Logger records structured information about each call to its Log, Debug, Info, Warn, and Error methods. For each call, it creates a Record and passes it to a Handler. - [Record](https://pkg.go.dev/golang.org/x/exp/slog#Record) contains data of a logging even. > A Record holds information about a log event. Copies of a Record share state. Do not modify a Record after handing out a copy to it. - [Handler](https://pkg.go.dev/golang.org/x/exp/slog#Handler) is a logging backend implementation, that handles records emitted from a Logger. > A Handler handles log records produced by a Logger. > A typical handler may print log records to standard error, or write them to a file or database, or perhaps augment them with additional attributes and pass them on to another handler. - [playground](https://go.dev/play/p/FewCi4X-JSu), copied from this article: <https://mrkaran.dev/posts/structured-logging-in-go-with-slog/> --- [release notes]: https://go.dev/doc/go1.20 [PGO]: https://en.wikipedia.org/wiki/Profile-guided_optimization