Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage Articles Book Review: The Go Programming Language

Book Review: The Go Programming Language

The Go Programming Language, written by Alan A. A. Donovan and Brian W. Kernighan, provides an excellent introduction to the Go language. It covers the most recent stable version of the Go programming language (1.5), which was released in August 2015. The reader is assumed to have existing programming experience in a C-like or Pythonesque language, although no particular language is expected. As Go is a compiled and typed language, those coming from similar languages will have a smaller learning curve than those coming from scripted or untyped languages.

The first half of the book covers the basics of the Go programming language, including the format and Unicode encoding of source files, variables, value types along with structures, maps, arrays and slices. This half concludes with Go’s approach to error handling using panic and recover.

The second half of the book focusses on Go’s unique features; object oriented programming without inheritance, implicit interfaces, and of course concurrency using goroutines. The book concludes with practical approaches to packaging and testing using standard Go tools as well as a reference to reflection and unsafe code.

Throughout the book, examples are introduced with sample code (available from the book’s website) which means that code can be executed (on Linux systems) using:

$ export GOPATH=$HOME/gobook            # choose workspace directory
$ go get         # fetch, build, install
$ $GOPATH/bin/helloworld                # run

Readers using Go on other systems will have to adjust the examples accordingly; for example, the GOPATH would be set using set GOPATH=“%HOMEPATH%\gobook” and run with %GOPATH%\bin\helloworld.

The first chapter (available from the book’s website) demonstrates the style of the book, and the way plentiful examples are shown in-line with the flow of the book’s text is followed throughout the remainder of the book.

The first chapter itself ramps up quickly, from running the traditional ‘hello world’ through implementation of Unix tools like uniq all the way to generating animated Lissajous graphics which are then returned from an HTTP server. Since Go is a Google language, the networking example also introduces the concept of a concurrent web crawler.

Although the first chapter is entitled “Tutorial” the reader may find that skipping over the Lissajous (and networking) examples is beneficial — particularly if they are not from a mathematical background. Fortunately these are merely samplers of topics covered later in the book at a more leisurely pace; after understanding more of the language the second half of the tutorial chapter will make more sense.

As well as the examples in the middle of the text, each section typically has a number of exercises that the reader is invited to try out. Learning by doing is far more beneficial to learning by reading; the exercises provide a number of challenges which provide increasingly bigger tasks that will improve the reader’s learning of the language.

The book describes the naming conventions used by Go, although the distinction between publicly visible identifiers (those that start with a capital letter) and privately visible identifiers (those that start with a lower case letter) is slightly hidden at the start of chapter 2. Existing Go users will know this as a standard, but skim readers could miss this out - especially since the effects of the distinction won’t be covered until the later chapter on packages.

That aside, the book contains many good pieces of advice, from how to deal with error conditions (and leaving early when an error is detected, thus avoiding the indenting pyramid of doom) through to using defer to register cleanup handlers, particularly for releasing mutex locks. The book doesn’t just cover the basics; there are particular nuggets of wisdom scattered throughout. A particular point of note is dealing with captured variables inside Go for loops, where due to the lexical scoping of variables it’s necessary to create a new variable with a different scope:

for _, dir := range tempDirs() {
  dir := dir // NOTE: necessary!
  // …

Types, structures, and functions and methods are given specific treatment, as their creation and use differs from other languages. The book explains how creating methods allow the receiver type to be specified, either as a value type or a reference, and allows the use of literals other than this or self. Using interfaces to define duck-typing on types or structs allows interfaces to be satisfied implicitly, including the empty interface type which is satisfied by any value. Errors are also covered in more detail in the context of interfaces, since errors are represented by an interface.

Any review of the Go programming language book would not be complete without the attention given to Go’s unique features; goroutines and channels. 65 pages - around 20% of the book - covers how concurrent programming can be achieved through the use of goroutines (asynchronously invoked functions), and how such goroutines can communicate with each other through fixed-sized (buffered) channels or synchronously (unbuffered). When such channels are being used to send simple signals, the book shows how to either use the channel’s closure as a trigger to perform certain actions, or to send sentinel data (typically consisting of a boolean value, an integer, or simply an empty structure) to achieve the same effect. The book also demonstrates how to use multiplexing selectors to receive or send on multiple channels.

The importance of using mutexes to protect data is also highlighted, not only to prevent data race conditions but also to highlight that on certain platforms the hardware may require strong barriers to be inserted to prevent code-reordering or cache line sharing which may produce inconsistent results. The book demonstrates different types of locks (such as simple mutexes or reader-writer locks) can be used, as well as showing the different performance profiles of different implementation choices.

These goroutines are used to demonstrate HTTP handling, both network connections from multiple clients as well as performing multi-threaded web scraping for links. The example created at the end of the chapters is that of a multi-threaded client/server chat network, where messages can be routed through between multiple clients whilst taking up minimal resources.

The book also demonstrates acquisition and testing tools using the go get and go test, as well as profiling tools for CPU, memory or mutexes. Finally the unsafe and reflection packages are briefly introduced, along with suitable warnings that these should not be used unless absolutely necessary.

The Go Programming Language is available as an electronic book from the publishers Addison Wesley, as well as a soft cover book through resellers.

About the Book Authors

Alan Donovan is a Staff Engineer in Google's infrastructure division, specializing in software development tools. Since 2012, he has been working on the Go team, designing libraries and tools for static analysis. He is the author of the oracle, godoc -analysiseg, and gorename tools.

Brian Kernighan was in the Computing Science Research center at Bell Labs until 2000, where he worked on languages and tools for Unix. He is now a professor in the Computer Science Department at Princeton. He is the co-author of several books, including The C Programming Language and The Practice of Programming.


Rate this Article