Book Review: Go Fundamentals

February 6, 2023

Very thorough, perhaps to a fault, this book is probably a great second read for most Go newcomers.

This is the eighth in my series of best books to learn Go in 2023. Read my conclusion or browse the entire series:


This book was published a couple of weeks after I made my initial purchase of books on Amazon, so was not included in my original stack of 6. An alert viewer of my YouTube channel alerted me to this book’s existence, so I immediately ordered a copy.

When it was delivered, I initially assumed Amazon had made an error, and sent me two copies of the book, because the envelope it came in was so thick. LOL. Nope! This is just a darned big book! 576 pages!

So buckle up for my review of this War and Peace novel of an introduction to Go!

Publication Details

Go Fundamentals by Mark Bates and Cory LaNou, 576 pages. Published December 3, 2022 by Addison-Wesley.

Audience

On the back cover we’re told this book “is specifically designed to get you up-to-speed fast, to leverage your existing knowledge of other languages, and to help you avoid common mistakes made by Go newcomers.”

The book also frequently compares and contrasts certain aspects of Go to other languages, for example when discussing compiled versus interpreted languages, integer overflow/wraparound, or errors versus exception handling. But in this context, familiarity with the other languages is not assumed, either, so you won’t be at a loss if you haven’t used Ruby, which is mentioned in one of the examples.

Narrative Style

For my personal taste, the narration style of this book is a little bit dry. It just gets to the point, without a lot of hand-holding. It’s not as “friendly” as, say Learn Go with Pocket-Sized Projects. It feels a bit more like a professor’s lecture, than like a friendly colleague walking you through something new.

There are places where I feel the book is also a bit more wordy than necessary. Re-iterating something, or perhaps expanding on a topic, in a somewhat repetitive way. As a simple example, when introducing strings in chapter 2, we read:

Strings exist within either back quotes (`) or double quotes (") in Go and have different charactaristics depending on which quotes you use.

If you use the back quotes, you are creating a raw string literal. If you use the double quotes, you are creating an interpreted string literal.

Interpreted string literals are character sequences between double quotes as in “bar”.

…snip…

Raw string literals are character sequences between back quotes.

I feel like these four sentences could easily be edited down to just one or two, without any loss of clarity, to avoid the feeling of repeating information.

Organization

The book is ordered in a very logical, progressive way. In the preface, it explains:

We have laid this book out with the idea that it is meant to be read from start to finish.

We have gone through great effort to try to make sure that examples and chapters don’t contain any new information that we haven’t covered up to that point. … Occasionally, we do have to break this rule, though. In those instances, we try our best to explain the concept or point to the chapter where it is explained.

To this end, the first chapter is about modules, packages, and dependency management, before even diving into how Go code is structured or written. This is great, because it means that Go modules (a topic frequently overlooked or ignored by other books) are covered right off the bat! But it does mean you’re not going to get as much instant gratification as you might from some other books, that dive in with a “Hello World” type example early on.

The only real head-scratcher I see, which isn’t a problem per se, is that chapter 4 covers both maps and control structures. I’m not quite sure why these two unrelated concepts are combined into a single chapter. Perhaps the authors felt that neither topic alone was long enough to justify its own chapter. 🤷

The progressive nature of the subject matter in this book does make for some unusual ordering of some topics. For example, it’s not until page 274 that we read a full discussion of avoiding dereference of nil values. The reason for this placement is that dereferencing a nil value in Go causes a panic. So this is discussed after the discussion of panic, panic recovery, and error handling. Error handling, in turn, is discussed after interfaces, since the error type in Go is an interface. From there, it discusses map initialization to avoid nil map dereferencing, even though maps otherwise are covered 5 chapters earlier.

The detailed table of contents makes it easy to see what to expect from each chapter. And the index is pretty extensive, as well, making this book a reasonable reference material. However, the ordering of topics does mean that many related topics aren’t always grouped together, so you may find yourself flipping between the index, and the two or three relevant portions of the book, to completely address a topic you’re looking up.

Content

Most important, this book hits all the highlights I’ve been looking for, with a full chapter dedicated to each: Go modules (along with packages), testing, and generics. This book also has full chapters dedicated to a few other topics that usually get much lighter treatment in the other books I’ve read. Errors (chapter 9), Channels (chapter 11), Context (chapter 12), and Sychronoization (chapter 13), each dive into the details and nuances of their respective topics in ways that I really appreciate.

For the topics covered, this book is incredibly thorough! It may indeed be overwhelming for some readers, for that reason. For example, in the first chapter, we learn a ton about dependency management. Including how to import multiple major versions of the same package—something rarely useful or adviseable (I think I’ve done it once, maybe twice, in 8 years as a Go developer). I question the value in exposing this level of detail to someone new to the language, before they even know how to write Hello, World.

At any rate, this level of detail does mean this book is for those who are content with delayed gratification, when it comes to actually writing useful Go code.

One small complaint I do have about the content of this book is a little bit subtle. On page 17, we’re shown the output of the go doc command:

This convention is repeated throughout the book, and it’s a clever way to demonstrate using the go doc command to learn about a library or function’s abilities. I applaud that. However, nowhere that I can find is the go doc command explicitly explained. And it doesn’t even appear in the index (although many of the other tools in the Go toolchain do). So the astute reader will pick up from the output examples that go doc is available and handy, but only by reading between the lines, as they say.

I was a bit surprised to find a couple of topics not covered in a book this size and otherwise detailed. In particular, neither iota (which is actually pretty important), and goto (which is honestly pretty unimportant) are covered in this book. (Or if they are, they’re buried somewhere I couldn’t find, and not mentioned in the index.)

Accuracy

In a book this large, there bound to be some errors. And I did find a few. But not many.

On page 113 while describing map initialization, for example, the book claims that “Unlike slices and arrays, maps cannot be initialized with a length and capacity.” This is not technically wrong, but it is a bit misleading, because the builtin make function does accept an optional “capacity hint” argument when initializing a map, which accepts, according to the Go spec, “an optional capacity hint as arguments”. This argument does not set a capacity limit, but it does allow the runtime to allocate the appropriate amount of memory to hold the designated number of elements. In effect, this is the same as initializing a slice by calling make with a capacity argument, since slice capacities can grow as well.

Perhaps a more serious example can be found on page 38, while describing the rune type:

A rune is an alias for int32 and is used to represent individual characters. A rune can be made up of 1 to 3 int32 values.

Now I don’t know what the authors meant here, but I suppose they’re trying to convey the fact that a rune may contain a multi-byte Unicode character. But this looks like a typo of some sort, because it’s plainly logically inconsistent to claim that an int32 can contain “1 to 3 int32 values”.

And a final example, of an ambiguous statement is in the first chapter. On page 4 we’re told “A package is a collection of Go files that share the same import path. These files are almost always in the same directory as each other.” But it doesn’t explain what exceptions exist to this almost always rule. (And I’m honestly unaware of any exceptions, so I’m quite curious!)

Physical Charactaristics

As I already mentioned, the first thing I noticed about this book when it arrived was its large physical size!

Aside from that, the paper quality is what I expect from a modern book, and it’s written with black type. I don’t recall seeing any graphics, illustrations, or even tables in the book. The code and output samples are printed in a monotype font, with minimal syntax highlighting (bold and italic) in the code samples. The main visual distinction between code samples and output samples is that the output samples have a small left border. For my personal taste, that makes the page a little bit busy. I would probably have preferred a 10% grey background. But I’m getting really nit-picky here.

Honestly, the only complaint I have about this book physically is that the typeface is a little bit hard for my aging eyes to read. And the index is written in an even smaller font, which I really struggle to read.

Conclusion

I’ll be leaving a 4-star review on Amazon for this book. I’d give it 4.5 if that were possible, but there are enough small things that aren’t ideal about this book to prevent it from earning a perfect score from me.

The biggest drawback is that the progressive build up of topics, that makes skipping around, and reading the full coverage of a given topic at once, a bit tricky. This is of course trade-off.

I think this means my recommendation for most people would be to read another, shorter book to get quickly up to speed on Go, then read this as a second book, to fill in a lot of the knowledge gap left by the shorter introductory book.


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Get daily content like this in your inbox!

Subscribe