The Go team has announced the release of Go 1.18, which brings support for generics, fuzzing, workspaces, and performance improvements.
The generics implementation provided by Go 1.18 follows the type parameter proposal and allows developers to add optional type parameters to type and function declarations. InfoQ has already covered the basic syntax of generics in Go when they first become available in Go 1.18 beta 1. In a nutshell, this is how you can define a function that works on a generic map
:
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
When calling this function, you can optionally omit the type arguments:
SumIntsOrFloats[string, int64](arg)
SumIntsOrFloats(arg)
The current generics design only supports a number of use cases, which should address the needs of the "majority of users". The Go team will continue their work on generics to support more advanced use cases in future releases. As pointed out by Michael Ernst, some of the current limitations can be circumvented, albeit at the expense of code cleanness and clarity.
While Go generics in 1.18 are considered stable, the Go team cannot rule out the possibility of bugs, not only at the implementation level but also in the design and specification.
These new language changes required a large amount of new code that has not had significant testing in production settings. That will only happen as more people write and use generic code.
The team also makes it clear that if any inconsistencies are found, that could require breaking changes in a future Go release, meaning a program using generics that worked with the buggy behaviour could not work anymore after the bugs get fixed.
For a quick start with Go generics syntax, you can check the official generics tutorial. The type parameter proposal gives instead a more complete view of what generics make possible their design, and provides a number of examples of use. For a more detailed description of this features, you have the language spec.
Go 1.18 also stabilizes support for fuzzing, a technique aimed at uncovering bugs by automatically generating tests that continuously manipulate inputs. Fuzzing can be especially valuable for security testing, but not exclusively.
Multi-module workspaces attempt to make it easier to manage multiple modules at the same time. Due to the fact the go
command recognizes only one single "main" module the user can edit, it was hard for developers to, say, add a new interface to a module, then use it in another module belonging to the same program. The gopls
command was an attempt to improve on this by automatically creating a supermodule. This had a drawback in that it introduced a mismatch between the set of versions used by the gopls
and go
commands. Workspaces provide a complete overhaul of module handling that should address all issues.
As a final note, Go 1.18 also improves compiler performance, which sees a 20% increase on Apple M1, ARM64, and PowerPC64 thanks to the expansion of Go 1.17’s register ABI calling convention to these architectures.