BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Go Generics Debut in Go 1.18 Beta 1

Go Generics Debut in Go 1.18 Beta 1

This item in japanese

The latest beta release of Go, Go 1.18 beta 1, finally introduces support for generics programming using parametrized types, a long-awaited and highly-requested feature. Additionally, it also adds support for test fuzzing, a technique used to find inputs then uncover incorrect behaviour in a program.

Generics entered Go's change proposal process early this year with preliminary work spanning over a couple of years and leading to a draft proposal which has now found its place in the language definition. While officially debuting now, generics in Go are still considered to be a preview aimed to gather feedback about what is working and what is not.

Generics are the most significant change to Go since the release of Go 1, and certainly the largest single language change we’ve ever made. With any large, new feature, it is common for new users to discover new bugs, and we don’t expect generics to be an exception to this rule; be sure to approach them with appropriate caution.

The idea behind generics is well understood as the possibility of representing functions and data structures factoring out the types they use. Go lacked this possibility, if we exclude the sort of genericity that is allowed by defining an interface type as a way to abstract on the type of the actual data that is passed in to a function.

The following snippet shows how you can define a function that works on a map containing either integers or floats, with K and V being two type parameters used to represent the actual types associated in the map:

func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
    var s V
    for _, v := range m {
        s += v
    }
    return s
}

In the code above, the K type parameter is used for the map key, which is required to be comparable, while V is the type of the values hold by the map, constrained to be either int64 or float64. When calling the function, you have the option of explicitly specifying its type parameters or let the compiler infer them from the passed arguments, when this is possible:

ints := map[string]int64{
    "first": 34,
    "second": 12,
}

floats := map[string]float64{
    "first": 35.98,
    "second": 26.99,
}

SumIntsOrFloats[string, int64](ints)
SumIntsOrFloats(floats)

Generics can be mixed with interface to allow the definition of type constraints that can be reused more easily. For example, the constraint int64 | float64 could be rewritten as Number using the following interface:

type Number interface {
    int64 | float64
}

While generics are the single most relevant new feature to Go 1.18, it is not the only one deserving a mention. In particular, Go 1.18 also introduces beta support for fuzzing-based testing and for a new Go workspace mode making it easier to work with multiple modules at the same time. For example, with Go workspace mode it is possible to modify a module providing a given interface along with other modules that are using it, thus bypassing the limitation that only one module may be the main module that can be edited while the others are loaded from the module cache.

Go 1.18 beta 1 is available for a number of platforms, including macOS, Linux, and Windows.

Rate this Article

Adoption
Style

BT