Yep, bitten by this one on repeat myself. definitely a WTF moment each time.
the fix was usually adding x := x
before go func() { do something with x }
`go` evaluates everything but the final function call in the context of the caller. So
go func (x int) { … } (x)
Will do the same, and is easier to extract to a named function. go func (x int) { do_work(x) } (x)
seems like a very roundabout way to say go do_work(x)
The "x := x" solution too suffers from this problem but slightly less: both idioms look like they are no-ops (while they are actually not) but at least "x := x" is weird enough to look like it was a deliberate choice, not some vestige from refactoring.Your first version is in fact a worse way to write the second one.
What's even the point of capturing the variable itself? To allow for writing inline callbacks that could sneakily mutate loop-local variables?
That’s how you’d do it using a [=] lambda in c++ or a move closure in rust.