What is the most common syntax error you make in Go? Many people may have different answers, but one of the most common answers is the use of variables in for loops. Even Go team developers, I have seen their commits make this mistake, not to mention other Go developers, like this problem at Let’s Encrypt, almost every Go developer has made this mistake, and this type of error has left a shadow on my heart, every time I write a for loop, I often use local variables to shade the loop variable, even if there is no problem.
Russ Cox checked 14,000 go modules and about 12,000 github repositories, searching for tricks like using
x := x to solve the loop variable problem, and found that about 600 commits were solving the problem, and upon closer inspection, about half of them were unnecessary.
For example, in the following two projects, one is necessary and one is not.
One of the loop variables is an interface, so it is not necessary. The other is a struct type, and the method Receiver is a pointer type, so it needs to be modified so that each loop is a different pointer.
So you see almost the same code, some are bugs and some are not bugs, don’t you hate it?
The circular variable problem has always been a problem and is not yet easy to detect; it exists in multiple types, such as
Or like the example at the top.
It is impossible to prevent. The most important reason is that the current loop variables
item, etc. are
per-iteration. This means that these loop variables are unique in this loop, not per-iteration.
The best trick to solve this problem is to use local variables (
x := x), such as:
People suffer from it, so there are some proposals to improve this syntax. For example, #20733, #24282, #21130.
Although the Go team has ignored this issue for many years, just the other day Russ Cox finally stepped in and created a discussion thread: #56010.
Because changing this syntax and changing the semantics of loop variables from
per-iteration breaks the promise of backwards compatibility, this change is still cautious and is still under discussion, but it is clearly a feature that Gopher expects to change.
And Russ Cox has also come up with a solution, if the feature is added in a certain version, such as
1.30, then if the version defined in the go module is smaller than this version of the library, then use the old
per-loop compiler, and if it is larger than this version, use