Source: https://castillobg.wordpress.com/2016/03/30/go-shot-range-captured-variables/
Golang: Readable code, decent package management, a nice concurrency model. Ah… such a cool language, isn’t it?
(ISN’T IT?)
That’s what I thought.
If your answer was no, then chances are you:
- Just don’t like gophers.
- Ran into the dreaded “
range variable captured by func literal
” gofmt warning.
If you’re in the first group, here: have a cute gopher pic:
For those in the second group, let’s take a look at the problem and an easy solution.
A very common scenario for goroutines are closures. That’s right, those (hopefully) little func
s inside another func
. It’s also very common to go through each element of a collection and launching a goroutine each time. That looks something like this:
Nothing funky about that apparently, right? Well, yeah, actually. Let’s look at a possible output (maps are iterated upon randomly, so there’s no guarantee 2 executions will be in the same order):$ go run myOpinions.go
What I think about Kanye West: Has some weird startup ideas, I guess?
What I think about Kanye West: Has some weird startup ideas, I guess?
What I think about Kanye West: Has some weird startup ideas, I guess?
Wait, what? One more time:
$ go run myOpinions.go
What I think about Napoleon: Tiny fella.
What I think about Napoleon: Tiny fella.
What I think about Napoleon: Tiny fella.
Even though there are 3 different entries in the map, we get the output for just one, three times!
This happens because the variables in the closure all point to the same value of the ones declared in the range
loop: their value is updated on each iteration.
Fortunately, we can fix this easily (check lines 19 & 20!):
Just assign the range variables to new ones!
'Programming' 카테고리의 다른 글
Linus Torvalds on C++ (0) | 2018.03.15 |
---|---|
Garbage collection considered harmful (0) | 2017.12.06 |
[Java] Classpath와 환경변수 (0) | 2017.02.10 |
Shared libraries with GCC on Linux (0) | 2016.12.04 |
(Java) 겁나 간단히 OOME 찾기 (메모리 분석하기) (0) | 2016.10.11 |