Introduction to Go 1.2

RED TEXT IS FROM THE 1.1 DOC AND NEEDS TO BE UPDATED. (It is here for formatting and style reference.)

Since the release of Go version 1.1 in April, 2013, the release schedule has been shortened to make the release process more efficient. This release, Go version 1.2 or Go 1.2 for short, arrives roughly six months after 1.1, while 1.1 took over a year to appear after 1.0. Because of the shorter time scale, 1.2 is a smaller delta than the step from 1.0 to 1.1, but it still has some significant developments, including a better scheduler and one new language feature. Of course, Go 1.2 keeps the promise of compatibility. The overwhelming majority of programs built with Go 1.1 (or 1.0 for that matter) will run without any changes whatsoever when moved to 1.2, although the introduction of one restriction to a corner of the language may expose already-incorrect code (see the discussion of the use of nil).

Changes to the language

In the interest of firming up the specification, one corner case has been clarified, with consequences for programs. There is also one new language feature.

Use of nil

The language now specifies that, for safety reasons, certain uses of nil pointers are guaranteed to trigger a run-time panic. For instance, in Go 1.0, given code like

type T struct {
    X [1<<24]byte
    Field int32
}

func main() {
    var x *T
    ...
}

the nil pointer x could be used to access memory incorrectly: the expression x.Field could access memory at address 1<<24. To prevent such unsafe behavior, in Go 1.2 the compilers now guarantee that any indirection through a nil pointer, such as illustrated here but also in nil pointers to arrays, nil interface values, nil slices, and so on, will either panic or return a correct, safe non-nil value. In short, any expression that explicitly or implicitly requires evaluation of a nil address is an error. The implementation may inject extra tests into the compiled program to enforce this behavior.

Further details are in the design document.

Updating: Most code that depended on the old behavior is erroneous and will fail when run. Such programs will need to be updated by hand.

Three-index slices

Go 1.2 adds the ability to specify the capacity as well as the length when using a slicing operation on an existing array or slice. A slicing operation creates a new slice by describing a contiguous section of an already-created array or slice:

var array [10]int
slice := array[2:4]

The capacity of the slice is the maximum number of elements that the slice may hold, even after reslicing; it reflects the size of the underlying array. In this example, the capacity of the slice variable is 8.

Go 1.2 adds new syntax to allow a slicing operation to specify the capacity as well as the length. A second colon introduces the capacity value, which must be less than or equal to the capacity of the source slice or array, adjusted for the origin. For instance,

slice = array[2:4:6]

sets the slice to have the same length as in the earlier example but its capacity is now only 4 elements (6-2). It is impossible to use this new slice value to access the last two elements of the original array.

In this three-index notation, a missing first index ([:i:j]) defaults to zero but the other two indices must always be specified explicitly. It is possible that future releases of Go may introduce default values for these indices.

Further details are in the design document.

Updating: This is a backwards-compatible change that affects no existing programs.

Changes to the implementations and tools

Godoc moved to the go.tools subrepository

A binary is still included with the distribution, but the source code for the godoc command has moved to the go.tools subrepository. The core of the program has been split into a library, while the command itself is in a separate directory. The move allows the code to be updated easily and the separation into a library and command makes it easier to construct custom binaries for local sites and different deployment methods.

Updating: Since godoc was not part of the library, no client code depends on the godoc sources and no updating is required.

The binary distributions available from

$ go get code.google.com/p/go.tools/cmd/godoc

The vet tool moved to the go.tools subrepository

TODO

Status of gccgo

The GCC release schedule does not coincide with the Go release schedule, so some skew is inevitable in gccgo's releases. The 4.8.0 version of GCC shipped in March, 2013 and includes a nearly-Go 1.1 version of gccgo. Its library is a little behind the release, but the biggest difference is that method values are not implemented. Sometime around July 2013, we expect 4.8.2 of GCC to ship with a gccgo providing a complete Go 1.1 implementation.

TODO

TODO: write prose

Changes to the go command

Additional platforms

The Go 1.1 tool chain adds experimental support for freebsd/arm, netbsd/386, netbsd/amd64, netbsd/arm, openbsd/386 and openbsd/amd64 platforms.

An ARMv6 or later processor is required for freebsd/arm or netbsd/arm.

Go 1.1 adds experimental support for cgo on linux/arm.

Performance

The performance of code compiled with the Go 1.1 gc tool suite should be noticeably better for most Go programs. Typical improvements relative to Go 1.0 seem to be about 30%-40%, sometimes much more, but occasionally less or even non-existent. There are too many small performance-driven tweaks through the tools and libraries to list them all here, but the following major changes are worth noting:

Changes to the standard library

foo.Bar

TODO: choose which to call out The various routines to scan textual input in the bufio package, ReadBytes, ReadString and particularly ReadLine, are needlessly complex to use for simple purposes. In Go 1.1, a new type, Scanner, has been added to make it easier to do simple tasks such as read the input as a sequence of lines or space-delimited words. It simplifies the problem by terminating the scan on problematic input such as pathologically long lines, and having a simple default: line-oriented input, with each line stripped of its terminator. Here is code to reproduce the input a line at a time:

Updating: To correct breakage caused by the new struct field, go fix will rewrite code to add tags for these types. More generally, go vet will identify composite literals that should be revised to use field tags.

Minor changes to the library

The following list summarizes a number of minor changes to the library, mostly additions. See the relevant package documentation for more information about each change.