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

© 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]
wheres
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.
Tools
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
Test
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.
Vet
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.
Gofmt
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.
Runtime
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.