Go 1.10 adds caching of successful test results & runs vet automatically during tests

JAXenter Editorial Team
Go 1.10

© Shutterstock / gguy

The wait is over! Go 1.10 is finally here and it comes bearing gifts (a.k.a. changes). Read on to find out what’s new.

According to the release notes, Go 1.10 improves caching of built packages, adds caching of successful test results, runs vet automatically during tests, and permits passing string values directly between Go and C using cgo.

There are no significant changes to the language specification.

Go 1.10 highlights

It’s that time of year again — another Go version has just been released. Although there aren’t any significant changes to the language specification, there are some minor alterations such as

  • A corner case involving shifts by untyped constants has been clarified. The compilers have been updated to allow the index expression x[1.0 << s] where s is an untyped constant [the go/types package already did].
  • The grammar for method expressions has been updated to relax the syntax to allow any type expression as a receiver; this matches what the compilers were already implementing.


Build & Install

Good news! The go build command now detects out-of-date packages purely based on the content of source files, specified build flags, and metadata stored in the compiled packages, according to the Go 1.10 release notes.

You don’t have to follow the old advice to add -a to force a rebuild in cases where the modification times were misleading for one reason or another (for example, changes in build flags) anymore. As of now, builds always detect when packages must be rebuilt.

Furthermore, the go build -asmflags-gcflags-gccgoflags, and -ldflags options apply by default only to the packages listed directly on the command line. The go build command maintains a cache of recently built packages, separate from the installed packages in $GOROOT/pkg or $GOPATH/pkg. The goal is to speed builds which don’t explicitly install packages or when switching between different copies of source code. You can now ignore the old advice to add the -i flag for speed, as in go build -i or go test -i since builds run just as fast without -i.

As of now, the go install command installs only the packages and commands listed directly on the command line. The result is that future commands will run as quickly as if the dependencies had been installed. If you want to force the installation of dependencies, you’ll have to use the new go install -i flag.

SEE ALSO: Go 1.9 is here


As of Go 1.10, the go test command caches test results. Therefore, if the test executable and command line match a previous run and the files and environment variables consulted by that run have not changed either, go test will print the previous test output, replacing the elapsed time with the string “(cached).”

However, keep in mind that test caching applies only to successful test results; only to go test commands with an explicit list of packages; and only to command lines using a subset of the -cpu-list-parallel-run-short, and -v test flags. The idiomatic way to bypass test caching is to use -count=1.

What’s more, it automatically runs go vet on the package being tested in order to pinpoint significant problems before running the test. If you’d like to disable the running of go vet, use go test -vet=off.

The new go test -json flag filters test output through the new command go tool test2json to produce a machine-readable JSON-formatted description of test execution.


As far as the go vet command is concerned, there’s [constant] access to complete, up-to-date type information when checking packages, even for packages using cgo or vendored imports. However, it should be noted that only go vet has access to this information; the more low-level go tool vet does not and should be avoided except when working on vet itself.


Two changes have been made to the default formatting of Go source code:

  • Certain complex three-index slice expressions previously formatted like x[i+1 : j:k] and now format with more consistent spacing: x[i+1 : j : k]
  • Single-method interface literals written on a single line, which are sometimes used in type assertions, are no longer split onto multiple lines.


The behavior of nested calls to LockOSThread and UnlockOSThread has changed. These functions control whether a goroutine is locked to a specific operating system thread, so that the goroutine only runs on that thread, and the thread only runs that goroutine.

Previously, there was no difference between calling LockOSThread once or more than once in a row  and a single UnlockOSThread always unlocked the thread. Now, the calls nest: if LockOSThread is called multiple times, UnlockOSThread must be called the same number of times in order to unlock the thread. Existing code that was careful not to nest these calls will remain correct. Existing code that incorrectly assumed the calls nested will become correct. Most uses of these functions in public Go source code falls into the second category.

Since a common use of LockOSThread and UnlockOSThread is to allow Go code to reliably modify thread-local state, the runtime now treats locked threads as unsuitable for reuse or for creating new threads.

Furthermore, stack traces only include implicit wrapper functions (previously marked <autogenerated>) if a fault or panic happens in the wrapper itself. Therefore, skip counts passed to functions like Caller should now always match the structure of the code as written [and should not depend on optimization decisions and implementation details].

The garbage collector now uses a smaller fraction of the overall CPU when running, but at the same time, it may run more of the time. The total CPU consumed by the garbage collector has not changed significantly.

The GOROOT function now defaults (when the $GOROOT environment variable is not set) to the GOROOT or GOROOT_FINAL in effect at the time the calling program was compiled. The GOROOT or GOROOT_FINAL was used in effect at the time the toolchain that compiled the calling program was compiled.

Check out the release notes here

Inline Feedbacks
View all comments