Errata

Learning Go

Errata for Learning Go, Second Edition

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
PDF Page Page 73
2nd paragraph

The paragraph starts comparing if statements to for statements and then refers to the wrong type in the 3rd sentence: "The if statement has three parts, separated by semicolons."

This should read "The for statement has three parts, separated by semicolons."

ie s/if/for/

Anonymous  Feb 21, 2024 
Other Digital Version github's code for ch04 ex1 and ex2
Line 11

"Write a for loop that puts 100 random numbers between 0 and 100 into an int slice." Since the problem does't say, I think 100 should be included in the list of random numbers generated.

The code at github at ch04's exercise_solutions/ex1/main.go#L11

uses `rand.Intn(100)` when it should use `rand.Intn(101)` if 100 is a valid number since the argument to rand.Intn() isn't included.

Also, this occurs at github at ch04's exercise_solutions/ex2/main.go#L11

Blair Zajac  Jul 27, 2024 
Other Digital Version Section: Type Assertions and Type Switches
Code sample containing "i2, ok := i.(int)"

In my Apple Books version:

i2, ok := i.(int)
if !ok {
return fmt.Errorf("unexpected type for %v",i)
}
fmt.Println(i2 + 1)

There's a missing space between in '",i'.

Blair Zajac  Aug 02, 2024 
Other Digital Version Section: Cgo Is for Integration, Not Performance
A few pages into the section

In my Apple Book version, there's this sentence:

'Put your C code into a .c file in the same directory as your Go code and include the magic header "cgo_export.h".'

Looking at the other sample code in the chapter, it looks like there's a missing _ in the filename, it should be `_cgo_export.h`.

Blair Zajac  Aug 02, 2024 
PDF Page p. 140
Paragraph beginning with GOMEMLIMIT (before Exercises of chapter 6)

The book says "Called thrashing, this results in a program that does nothing other than run the garbage collector."

Thrashing occurs with systems having virtual memory and is not directly related with garbage collection, according to my understanding.
I think some rewriting is necessary with this paragraph.

Shun Urushido  Sep 08, 2024 
ePub Page Ch 2, Predeclared Types / Literals
Literals, integer literals (2nd para)

It currently reads: "Integer literals are base 10 by default, but different PREFIXES are used to indicate other bases: 0b for binary (base 2)"

Corrected, it should read:
"Integer literals are base 10 by default, but different SUFFIXES are used to indicate other bases: 0b for binary (base 2)"

Prefixes come before; suffixes come after.
b0 would be 0 prefixed with b.
0b would be 0 suffixed with b.

Peter D'Souza  Oct 01, 2024 
Printed Page Chapter 14, page 362
2nd and 3rd paragraph

Example of context.WithErrorClause missing select statement in the status and delay goroutine which potentially can lead to goroutines stuck trying to write to chan.
Theoretically, it can happen when one of the goroutines writes to chan, "at the same time" ctx is cancelled, main goroutine reads ctx.Done() before reading a value from chan and breaks the for select loop. So any other goroutines will be blocked trying to write to a chan and without select statement they won't be able exit
I could not reproduce that scenario but using select statement is the right approach to handle such cases

2nd paragraph:

select {
case ch <- "success from status":
case <-ctx.Done():
}
time.Sleep(1 * time.Second)

3rd paragraph:

select {
case ch <- "success from delay: " + resp.Header.Get("date"):
case <-ctx.Done():
}

Kanstantsin Tatarchuk  Oct 26, 2024 
Printed Page Pg 141
CH06 Exercise 2

The exercise solution doesn't consider what happens if an empty slice is passed into the updateSlice function. An empty slice causes the compiler to panic with an index error.

Jim  Dec 29, 2024 
PDF Page p144
in the note.

This means that *tthe* type has a specified way to store its data and provides
an implementation of any methods declared on the type.

Jin Cao  Apr 01, 2025 
Printed Page 5
line 6

An unnecessary comma inside the quotation marks for binary name "hello," -> should be "hello".

Dmitrii  Apr 01, 2024 
Printed Page 73
4th paragraph

i{plus}{plus} seems strange

Simon  Feb 24, 2024 
Printed Page 85
First multi-line paragraph

"Also as if an if statement" should be "Also, as IN an if statement". I think you want "in", and I would also add that comma after "Also".

Kent Johnson  Oct 01, 2025 
PDF Page 102
2nd code

The code in the book is different from the code in The Go Playgound:

expressions := [][]string{
{"2", "+", "3"},
{"2", "-", "3"},
{"2", "*", "3"},
{"2", "/", "3"},
{"2", "%", "3"},
{"two", "+", "three"},
{"5"},
}

should be:

expressions := [][]string{
[]string{"2", "+", "3"},
[]string{"2", "-", "3"},
[]string{"2", "*", "3"},
[]string{"2", "/", "3"},
[]string{"2", "%", "3"},
[]string{"two", "+", "three"},
[]string{"5"},
}

Anonymous  May 22, 2024 
PDF Page 110
4th paragraph

(I cover at methods in Go in Chapter 7.)

(I cover methods in Go in Chapter 7.)

"at" is not necessary, right?
You do not use "at" in the code.

Anonymous  May 28, 2024 
Printed Page 130
Second-to-last line

In the sentence "Run the command go test ./… -bench=. to find […]", the three dots in "./…" appear to be formatted as an ellipsis, rather than three individual dots.

This is clearly a super minor thing, especially since it's in the print edition and we can't exactly copy-paste the command. (I don't know if it's the same in digital formats.) Then again, the formatting sent me off to try using an ellipsis, and it does not work.

Martin Lehmann  Nov 01, 2024 
PDF Page 131
4th line after the section title "The Difference Between Maps and Slices"

The books says "a map is implemented as a pointer to a struct."

But it is NOT true, isn't it? Maps are implemented using hash tables, right?
Deleting "to a struct," or changing "to a struct" to "to a structure representing a map" (or the like) would be clearer, I think.

Shun Urushido  Sep 06, 2024 
PDF Page 144
2nd paragraph

There is an extra t in "This means that tthe type has a specified way to store its data and provides an implementation of any methods declared on the type"

s/tthe/the

Anonymous  Feb 23, 2024 
Printed Page 144
line 7

"tthe" instead of "the"

Dmitrii  Apr 11, 2024 
PDF Page 151
the 1st and second paragraph of "Types Are Executable Documentation"

The first paragraph tells about "one user-defined type that’s based on another user-defined type" and the second paragraph also tells about "one user-defined type based on another user-defined type."

It seems to me, the first paragraph should only tell only about "a user-defined type based on other built-in types" and should NOT tell about "one user-defined type that’s based on another user-defined type."


i.e.
"or one user-defined type that’s based on another user-defined type" in the first paragraph is better to be deleted.

Shun Urushido  Sep 10, 2024 
PDF Page 174
1st paragraph

You say "In the preface, I compared writing software to building bridges. "
but no bridges were mentioned in the preface.

I think you mentioned the bridges in the preface of the 1st edition!

Anonymous  Jul 30, 2024 
Printed, PDF, ePub Page 175
3rd paragraph (not counting code)

Text reads as

> By a stunning coincidence, LoggerAdapter and SimpleDataStore happen to meet the interfaces needed by your business logic, but neither type has any idea that it does.

I was confused by this and realized that it was a typo; we just defined LoggerAdapter and DataStore interfaces, so the text should read

> By a stunning coincidence, LoggerAdapter and DataStore happen to meet the interfaces needed by your business logic, but neither type has any idea that it does.

Anonymous  Feb 11, 2024 
Printed, PDF, ePub Page 175
3rd paragraph (not counting code)

Text reads as

> By a stunning coincidence, LoggerAdapter and SimpleDataStore happen to meet the interfaces needed by your business logic, but neither type has any idea that it does.

I was confused by this and realized that it was a typo; we just defined LoggerAdapter and DataStore interfaces, so the text should read

> By a stunning coincidence, LoggerAdapter and DataStore happen to meet the interfaces needed by your business logic, but neither type has any idea that it does.

Stanley Chan  Feb 11, 2024 
Printed, PDF, ePub Page 196
"More on comparable" section

Typo

> As you saw in “Interfaces Are Comparable” on page 165, interfacesare one of the comparable types in Go.

interfacesare does not have a space in between. Should read as

> As you saw in “Interfaces Are Comparable” on page 165, interfaces are one of the comparable types in Go.

Stanley Chan  Feb 27, 2024 
Printed Page 196
Under the heading "More on comparable"

First paragraph under "More on comparable" heading, the word interfacesare should have a space.

Rik Jurriaans  Aug 31, 2025 
PDF Page 242
line 6

You do "go build" first and then "go get ./..." in the page, but isn't it better to use "go mod tidy" to update the dependency?
I do not know why you just do not use "go mod tidy."

If you do "go mod init xxx", the system prints the following message at the end:

go: to add module requirements and sums:
go mod tidy

Why don't you follow this?


Shun  Dec 19, 2024 
PDF Page 289
the last line

"with native threading" should be "WITHOUT native threading"???

Shun Urushido  Oct 01, 2024 
PDF Page 307, Concurrency Practices and Patterns, When to use buffered and unbuffered channels
6th paragraph, under the code example

This means we can
create a buffered channel with one space for each launched goroutine, and
have each goroutine write data to this **goroutine** (<- this should be "channel") without blocking.

Cristian Chira  May 15, 2024