Tap the power of Google's Go language

Learn the key concepts behind programming in Go, a concise, simple, safe, and fast compiled language with powerful concurrency features

1 2 Page 2
Page 2 of 2

Use canonical import paths for repositories with aliases

Some Go packages have repositories on standard hosts (for example, Bitbucket, GitHub, Google Code, and Launchpad) but also have an aliased path, such as rsc.io/pdf for https://github.com/rsc/pdf. The aliased path improves the stability of go get for the case where the repository is moved to a different host; the aliased site serves HTML meta tags pointing to the current repository.

That introduces two potential problems for imports of Go code. An import for the current actual repository may break in the future, and the package may be imported twice from different paths.

To fix this problem, Go has a canonical import path declaration comment:

package pdf // import "rsc.io/pdf"

Once such a comment appears in at least one source file in the package, go get will fail on any other import path.

Vet your Go programs

Many languages have one or more lint tools to provide static code checking in addition to that provided by the compiler. Go has vet, which examines Go source code and reports suspicious constructs. vet can be used in three ways:

$ go vet package/path/name

This checks the code in a named package.

$ go tool vet source/directory/*.go

This vets the files named, all of which must be in the same package.

$ go tool vet source/directory

This recursively descends the directory, vetting each package it finds.

The example below shows the third form applied to the gocode tool's source code. By default, all non-experimental checks are run.

go vet lg IDG

Trace your Go programs

Trace and profiling facilities are essential to understanding what's actually going as your code executes. Without them, you'd have to write a whole lot of fmt.Printf statements, which falls into the category of "a real programmer can write Fortran in any language."

The Go language has three ways to generate trace files: running the go test -trace command, using the runtime/trace package in your code, and using the net/http/pprof package in your code. To view trace files, use the go tool trace command.

As shown in this presentation by Google's Dmitry Vyukov, the Go trace tools can generate a graphical display that will give you a good feel for the behavior of your code. Options include viewing the trace in a web browser and generating a pprof-like profile from the trace, using any of four profile types.

Use the race detector

Race conditions, where the output is dependent on the sequence or timing of other uncontrollable events, are the bane of programmers who use concurrency—and concurrency is the rule rather than the exception for Go programs. Enter the data race detector.

go race Google

You can enable the race detector by adding the -race flag to any of the go commands:

$ go test -race mypkg    // test the package
$ go run -race mysrc.go  // compile and run the program
$ go build -race mycmd   // build the command
$ go install -race mypkg // install the package

Unfortunately, there's a cost to enabling the race detector. Execution time can be increased by an order of magnitude, so you may only want to use it in tests or in one instance among many production instances. In addition, the race detector only finds races that happen at runtime, so it can't find races in code paths that are not executed. Nevertheless, the race detector is useful enough that the Go authors have incorporated it into their continuous integration process.

You can use the GORACE environment variable to set the log path and other variables for programs built with the -race flag.

Use arbitrary precision Float types (in math/big)

Sometimes you need to do floating-point calculations to more precision than is available from IEEE-standard Float64 arithmetic. The Go language math/big package can give you what you need, as shown in the example below for calculating the square root of 2 to 200 bits of precision using Newton's method.

go big float IDG

Is that slower than simply taking math.Sqrt(2.0) or using the constant math.Sqrt2 (1.4142135623730951)? Of course. But when you need more precision, it's certainly worth the extra time and code to get it.

Use sort.Stable to preserve input order of equal values

Sort stability is when two objects with equal keys appear in the same order in sorted output as they appear in the input unsorted array. Some sorting algorithms, such as insertion and bubble sort, are inherently stable. Others, such as heap and quick sort, are not.

You often care about the stability of a sort operation if it is one of a sequence of sorts—for example, sorting rows of a table by multiple columns. Otherwise, you may not care.

The Go sort.Sort function is not guaranteed to be stable, but it's fast: It makes one call to data.Len to determine n, and O(n*log(n)) calls to data.Less and data.Swap. By contrast, the Go sort.Stable function sorts while keeping the original order of equal elements. It's slower, however, making one call to data.Len to determine n, O(n*log(n)) calls to data.Less, and O(n*log(n)*log(n)) calls to data.Swap.

Keep going with Go

As we've seen, the Go language embodies a rather opinionated set of capabilities that fixes many of the problems that experienced programmers have with other languages, such as long build times, arcane toolchains, and baroque inheritance schemes. In fact, the Go language authors point it out in their FAQ:

  • It is possible to compile a large Go program in a few seconds on a single computer.
  • Go provides a model for software construction that makes dependency analysis easy and avoids much of the overhead of C-style include files and libraries.
  • Go's type system has no hierarchy, so no time is spent defining the relationships between types. Also, although Go has static types the language attempts to make types feel lighter weight than in typical OO languages.
  • Go is fully garbage-collected and provides fundamental support for concurrent execution and communication.
  • By its design, Go proposes an approach for the construction of system software on multicore machines.

The resources and walkthroughs that follow should help you grok the Go language. Go forth and code.

Copyright © 2017 IDG Communications, Inc.

1 2 Page 2
Page 2 of 2