What's New in Go 1.18
Generics, Test Fuzzing, Optimization for AMD64, Workspace Mode, and More
It is that time of the year again: a new Go release is around the corner. The Go team has just made Go 1.18 release candidate 1 (go1.18rc1) available, with the expectation of releasing Go 1.18 by the end of February 2022.
Go 1.18 is one of the most anticipated Go releases in a long time, and for good reasons. Go 1.18 implements initial support for generic types and functions, which is the most wanted — and perhaps the most debated — feature by the Go community.
In addition to Generics, Go 1.18 packs many other great features such as support for testing fuzzing, micro-architecture support and optimization for AMD64 CPU's, changes to the go
tool including support for "workspace" mode, several updates to the core libraries, and many bug fixes and minor updates to the standard library.
Let's take a look at some of the main updates.
Support for Generics
Generics is the most anticipated feature in this release. Go 1.18 supports an initial implementation of generic types and functions according to the Generics proposal. With this new addition, the language supports declaring parameterized types and functions that can be later instantiated with different arguments types.
The use of generics improves general code re-usability by allowing you to consolidate sets of functions or types that have similar implementation but operate on different input types into single entities that are easier to test and maintain.
For example, it's common for some libraries to have code similar to this:
func SumInt(a, b int) int {
return a + b
}func SumFloat32(a, b float32) float32 {
return a + b
}func SumFloat64(a, b float64) float64 {
return a + b
}//func sum...
By using a generic function, you can consolidate all these functions into a single function:
func Sum[T constraints.Ordered] (a, b T) T {
return a + b
}
Because this is a major change in the language and it's a brand new feature, there are some limitations, potentially some performance impacts, and possibly unknown issues. Be mindful of these uncertainties when deploying generic code in production.
For more information about generics, take a look at the release notes and the updated language specification.
Test Fuzzing
Another welcome addition to Go 1.18 is the support for test fuzzing. Fuzzing is a software testing strategy that involves providing a large number of random input parameters, including many edge cases, to the code being tested with the goal of catching errors, exposing bugs, triggering exceptions, and discovering vulnerabilities that are otherwise hard for humans to detect.
Go test fuzzing adds a new type to the testing
package testing.F
and expands Go's current features and strategies such as Table Driven Testing. Prior to this release, you could use external libraries to perform test fuzzing but the addition of fuzzing to the standard tooling will provide better support and easier access to more developers.
🌟 Be aware — the Go team alerts us that the current fuzzing implementation uses a lot of system resources and may impact your system's performance during execution.
For additional details, consult the Go Fuzzing documentation.
Micro-Architecture Optimization for AMD64 CPUs
Go 1.18 introduces micro-architecture optimization for AMD64 processors. You can now use the new Go environment variable GOAMD64
to select one of four micro-architecture targets v1
, v2
, v3
, or v4
to instruct the compiler to optimize the resulting binary for specific CPU features. It results in optimized binary instructions that are incompatible with processors that don't have those features.
The default value for the variable GOAMD64=v1
results in binary instructions that are compatible with all 64-bit x86 processors.
For more details about this feature, consult the Architecture section of the minimum requirements page.
Go Workspace Mode
Finally, for the last highlighted update, Go 1.18 introduces a new workspace mode support for the go
command, which allows you to work on multiple modules at the same time. Previously, working with multiple modules was not easy and could cause issues with the tooling and IDEs. This new feature solves these issues, bringing along changes to other tools, such as gopls
, to streamline working with multiple modules.
With this change, if the go
command or tooling finds a file named go.work
in the current or a parent directory, it will run in workspace aware mode. It then uses the content of this file to determine which modules to use for dependency resolution instead of using go.mod
file.
In Go 1.18 you can use the go work
command to create and manage go.work
files. For more information consult its documentation.
For a more detailed explanation of the workspace feature and a rundown on many other Go 1.18 improvements, check episode 217 of the Go Time podcast.
What's Next?
This article is a quick summary of the main updates coming with Go 1.18, but there are many additional bug fixes and minor improvements to the tooling, compiler, and the standard library. For a complete list, take a look at the Go 1.18 release notes.
If you can't wait for the final release in a couple of weeks and you want to start testing Go 1.18 right now without installing it on your machine, visit the Go Playground and select Go Dev Branch from the Go release drop-down. You can also run it as a container using Podman or Docker.
If you prefer to have it installed on your machine so you can test with some of your code, download Go 1.18 RC1 to your local machine by following the instructions on the download page.
If you enjoyed this article, you might also enjoy Ricardo’s book, published by The Pragmatic Bookshelf:
Write your own fast, reliable, and cross-platform command-line tools with the Go programming language.