- Most information was taken from the release notes.
Release is schedules for February 2023. Releases happened between 16th and 25th in the past, so I assume that 1.20 will be released end of February as well.Final release was on 1st of February 2023, a little bit earlier than usual for an even version number Go release.- I talked about this in our #34 Leipzig Gophers Meetup.
Context
Package context received 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)
Errors
Support for wrapping multiple errors:
- errors.Join to wrap multiple errors into one (error messages will be newline delimited)
- fmt.Errorf now also supports multiple %w format verbs
- (playground)
HTTP Response Controller
http.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 and write deadlines using the response controller.
Language Changes
Slice to array conversions are now a bit easier to write (playground).
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. 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, in increasing index order
- Note that slices still cannot be checked for equality using the
==operator!
- Note that slices still cannot be checked for equality using the
- 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, sound obvious, right 😅? In practice this means that a comparable constrained type parameter can be instantiated with non-strictly comparable types, like interfaces. As an example, you can do the following from Go 1.20 (playground):
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 -jsonwill emit a startActionat the beginning of each test execution.- The
gocommand received a-Cflag, to change working directory. - Build related commands,
go buildandgo install, received a-coverflag to build with code coverage instrumentation. There will be a separate talk today, that is going to cover this topic in detail. netandos/userpackages are now pure Go packages under macOS, i.e. they don't requirecgoanymore.cgois 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). Allocations from the memory arena are not considered by the GC and the arena will be freed manually all at once. (package docs). 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/ecdhandcrypto/ecdsapackages which replaces the more low-levelcrypto/elliptic. Fillipo Valsorda wrote a deep-dive on the Go 1.20 crypto changes, e.g. the elliptic curve crypto packages don't rely onmath/biganymore, which makes them constant time. - ReverseProxy Rewrite hook superceeds
httputil.Directorand now receives in- and outbound requests with its*httputil.ProxyRequestargument (unlike a Director function which just received an outbound request).
Minor standard library changes
archive/tarandarchive/zipreturnErrInsecurePathif an entry has an absolute path, contains invalid characters etc. Note that this is currently behind a feature flag,GODEBUG=zipinsecurepath=0but might get the default in a future release.- the
bytespackage receivedClone, which basically returns a clone of the given byte slice. This is a useful utitlity with a pretty minimal implementation.TrimPrefixandTrimSuffixgot siblings, calledCutPrefixandCutSuffix. The difference is that theCutfunctions will return if something was removed or not.
crypto/tlsTLS certificates are now shared across all clients using a certificate, which might lead to significantly less memory usage. If a handshake fails a newCertificateVerificationErroris returned.io.OffsetWriterbasically wraps anio.WriterAtand adds a given fixed offset to each Seek, Write etc. call.- Directory trees are usually traversed using
fs.Walk. There's a newSkipAllerror that can be used to immediately stop the recursion offs.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/randwill automatically seed the global RNG, this can deactivated withGODEBUG=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.Bcan now report the elapsed time
Future
- There's a proposal to add structured logging support to the standard library with package
log/slog - Can be used already by importing
golang.org/x/exp/slog - Currently
- we only have package
log, a simple logger that has no support for levels etc. - every logging library needs to define their own
Loggerinterface
- we only have package
- At a high level
slogis build from three parts:- 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 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 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.
- Logger is user-facing part of the API, exposing methods like
- playground, copied from this article: https://mrkaran.dev/posts/structured-logging-in-go-with-slog/