1) In Go, the 'i' variable in the for loop is the same 'i' for each round of the iteration, meaning closures created inside the loop all refer to that same 'i' variable, instead of getting their own copy of it. Very easy to accidentally think the all closures have their own copy of 'i'. Goroutines are only mentioned because in Golang this mistake tends to come up with Goroutines because of a common code pattern.
OR
2) Goroutines themselves either behave or have some weird lexical scope rules in a way I don't know and it doesn't really have to do with closures but an entirely Golang-foreign-alien concept to me I cannot see, and this is why the book example had Goroutines mentioned with the mistake.
I rarely write Go myself so I was curious :) It looks like it was 1) unless I am bad at reading, and I think the Go 1.22 change is good. I could easily imagine myself and others making that mistake even with the knowledge to be careful around this sort of code (the link shows a more complicated example when scrolling down that IMO is a good motivating example).
You think you're working with a value but you're actually working with a reference to a value under the hood.
"We might expect this code to print 123 in no particular order" should really say "exactly" or "in order", since it's proved in the next paragraph to be inconsistent.
And that would be the layman's explanation of concurrency resulting in things added sequentially happening out of order.
And assuming FIFO on async execution, akin to running everything in series, is probably the first mistake anyone will make when they encounter concurrency for the first time.