3 ms·
This seems to me to be the same class of error as those that aren't so much a go thing as a very comma gotcha for closures; you're placing x in the scope of the
by singular 13y ago
This seems to me to be the same class of error as those that aren't so much a go thing as a very comma gotcha for closures; you're placing x in the scope of the for loop and passing it into a series of anonymous functions, so it gets closed over and referenced as a common variable between each of those functions; thus before each goroutine has a chance to run the loop has completed and x == 3. You'll find this behaviour in any language with closures.
In the second example you're allocating a new local variable on each iteration, so each individual value gets closed over separately. That's probably not what you'd want usually, hence that not being default behaviour.
- ridiculous_fish 13y agoNot all languages with closures work this way. In Objective-C blocks, the default is to capture locals by value, so this sort of error is less likely. In C++11 lambdas, you have to specify the capture type as well. Capturing variables by value has both safety and performance benefits in a multithreaded world, and it's unfortunate that Go chose not to do that.
- singular 13y agoNot sure why you were downvoted! That's interesting. I can see why, this seems a rather common gotcha.
- cdoxsey 13y agoRight. I'm just saying I think the scope ought to be different. The 'x' in the loop should be a new variable each time because its not really 'a common variable between each of those functions'. In the for i := 0; i < 10; i++ {} case it's definitely more clear that i should be the same thing between iterations. (So you can tinker with i inside the loop) It just seems like they could've done something different for the 'range' for loop. Javascript is plagued with this same problem (though its even worse because it doesn't even follow { } blocks)
- singular 13y agoAfter I wrote my reply I played around with some C# and found to my surprise that foreach does in fact provide a new variable to be captured on each iteration, so clearly this is a design decision that varies between languages.