"The Go Programming Language” by Alan A.A. Donovan & Brian W. Kernighan
Like many other programmers, I learned to write C by reading “The C Programming Language” by Kernighan and Ritchie, the book known to hackers everywhere as “K&R”. I confess that I was initially drawn to “The Go Programming Language” out of sheer Kernighan brand awareness. Would it be the K&R of the Go world? I certainly hoped so, as I have strong preferences when it comes to programming language textbooks.
First of all, I like my textbooks to be concise. “The Go Programming Language” is almost exactly the same width and height as K&R, but about twice as thick. Some of that is down to paper thickness, though — it weighs in at 380 pages vs (my copy of) K&R's 272 pages. It's no programming doorstopper.
“The Go Programming Language” is aimed at people who are already programmers, another thing I look for. I've written code in well over a dozen programming languages at this point, so the last thing I need is a chapter on what variables are or what a pointer is.
My third major preference is for examples over theory. Knuth's “Art of Computer Programming” books, for example, are far too mathematical for my taste. I find math fascinating, but when it comes down to it I'd prove De Morgan's laws by writing a program to dump out truth tables, not by doing the math. I also like the examples in a book to be things I might want (or at least need) to do, and this is an area where this particular book shines. Examples include building an Internet chat server, building a parallel download utility, calling a JSON API, converting dates and times, and so on. Chapter 9 even goes through the construction of a useful concurrent non-blocking cache implementation.
The overall structure of the book resembles K&R, too. It opens by diving straight in to some examples, including a simple web server and code to draw some animated GIFs. By chapter 3 you're drawing 3D surfaces and Mandelbrot sets. The general approach seems to be to take the reader on a whirlwind tour for a few chapters, convince them that it's worth continuing to read the whole book, and then go back and cover topics in more detail. Sometimes a topic gets visited three or four times before the book gets to the bottom of it, so I recommend taking notes using an outliner or some other tool that lets you insert extra material later.
Mostly the book's structure works, but occasionally details were omitted that I couldn't help wondering about. For example, page 12 puts a
* in front of the
os.File type without any explanation of what it means. Even knowing that it indicates a pointer, I couldn't work out why that type in particular needed to be a pointer in the example, when other structures didn't. (That particular mystery wasn't really resolved until chapter 6.) On several occasions I ended up searching the Internet for answers. I still don't know what
//!- comments mean in the example code, if anything.
Another thing that struck me as odd was that after covering structs, the book dived into JSON serialization and deserialization and templating, before it had even discussed how objects work. I'm being picky, though — the book did eventually cover the material, I just needed to relax and be patient and save my questions for the relevant chapter.
While the book is largely about the nuts and bolts of programming in Go, it does also cover some of what you might call the philosophy of the language — why it's the way it is, and not like (say) C++, Rust or Scala. There's also discussion of the benefits of encapsulation and its downsides, how to do unit testing, what recursion is, and so on.
There are two chapters on the problems of concurrency and shared data. This is necessary, given Go's focus on concurrency — yet it's also not enough. For example, the book talks quite extensively about race conditions and how to avoid them, but not so much about deadlocks (except as a side effect of bad mutex use). A separate book on concurrent programming would be advisable for those new to it; perhaps “Advanced Concurrent Programming With Go” is already in the works as the obvious sequel.
One thing K&R had which is missing in “The Go Programming Language” is a reference section. This book has no list of the standard libraries or APIs in Go 1.x, so you'll need to refer to the web site at golang.org for that information. To give some specifics, the book doesn't cover linked list data structures, logging, database access, or calling other processes. This is a bit of a shame, as at the time of writing the API documentation on the web is often minimal at best. On the other hand, I can understand that the APIs might still be too much of a moving target to be worth committing to paper, and including them all would have turned the book into a doorstop. I think the right decision was made, for now; just be aware that this is a book to teach you the core language, not a reference manual.
And with that said, my conclusion is that it's an excellent book. By the time I was finishing reading it, things which had confused me during my early attempts at writing Go code were making perfect sense. If you're a programmer and want to learn Go, this would be my recommendation for the first book to get.