The Go programming language has evolved a lot since it was first published in 2009. Go 1.18 was a highly-anticipated release due to its support for generics and many other important updates.

Go released version 1.18 in March 2022. Here's the low-down on the most significant changes.

Support for Generics

Generic programming lets you write functions that can accept and return more flexible types.

Before support for generics, you needed to explicitly state parameter types and return types. The simplest form of generics allows you to specify untyped parameters:

        func PrintAnything[T any](thing T) {
    fmt.Println(thing)
}

But generics offer much more power than just this. You can declare almost any combination and granularity of type for parameters. For example, you can use the constraints package to write a function that operates on any value that you can order. This includes int, floats, and strings. Here's an example that demonstrates the syntax:

        import "golang.org/x/exp/constraints"
 
func Max[T constraints.Ordered](input []T) (max T) {
    for _, v := range input {
        if v > max {
            max = v
        }
    }
 
    return max
}

Note that this function uses the generic type, constraints.Ordered, to declare its parameter and its return type.

Generics provide for uncertainty and flexibility in code. The Generics proposal and changes are backward compatible.

Fuzz Testing

Fuzzing is a software testing technique that validates a program with erroneous, unexpected, or unpredictable data.

The testing package introduces fuzzing in 1.18, so to define a fuzz, you have to import it from the standard library:

        import "testing"

After importing the testing package, you can pass an identifier of type *testing.F to the test function.

        func testFunc(f *testing.F) {
    // your code
}

Fuzzing generates input parameters for testing code. The outcome of fuzzing is unpredictable since the inputs are not user-defined. Fuzzing should help you write better code tests and catch bugs you didn’t know existed.

Go Workspace Support

Workspaces are directories of similar source code that make up a project or a bigger unit. Workspaces make it easier to manage and debug code by grouping similar code based on functionality.

Conventionally, you subdivide Go projects into source code (src) and executable files (bin). The Go toolchain builds source code from the former into executables in the latter. Go workspaces allow developers to work with multiple workspaces using Go modules with a particular main module.

The command for creating workspaces is:

        $ go work <command>

Use the work command with subcommands like:

  • init → creates a workspace in the specified directory.
  • use → adds a new module to go.work, the go workspace file.
  • edit → edits the go workspace file.
  • sync → synchronizes dependencies from the build list to the workspace modules.

The inclusion of workspaces to go would increase productivity as planned in developing the language.

Performance Improvements

Go version 1.18 now supports ARM64 Apple M1 and 64-bit PowerPC in the ABI calling convention. This results in over 10% gain in CPU performance for users of these devices.

Declared and unused variables in functions are now logged as errors on program compilation.

The go build command, along with other related commands, supports the -asan flag, which supports interoperability with C/C++. This will help Go developers use Go programs with C and C++ programs.

Other Important Updates

The go get command no longer installs packages in module-aware mode, which is a big change from when you first got started with Go. The go install command replaces get to adjust module dependencies across workspaces.

Since the type checker now handles generics, error messages may log differently than in previous versions.

Time taken for programs to compile may be slower in 1.18. But this will not affect execution time once Go has compiled your program.

You can find the full details of all the latest changes in the release notes for Go 1.18.

Go 1.18 Has Several Diverse Additions

Using Go 1.18, you can now write generic code, test efficiently using fuzzing, and switch between Go modules using workspaces. You can even write code that works in conjunction with C and C++ programs.