That’s actually what I meant to indicate in the last paragraph (emphasis added by me):
> The code in the Reddit post takes advantage of the fact that the last > increment of the C-style loop can be observed outside the loop, But thanks for providing a clarification. I see now it has not been clear to everyone. > On Wed, Jul 26, 2017 at 08:44:46AM -0700, Christoph Berger wrote: > >>> someone shared [this question]( >>> https://www.reddit.com/r/golang/comments/6paqc0/bug_that_caught_me_with_range/) >>> >>> on reddit. I must say, that I'm surprised by the behavior myself. I would >>> have expected >>> for i = range v >>> to be semantically equivalent to >>> for i = 0; i < len(v); i++ >>> and don't really understand the reasoning behind choosing different >>> semantics. Note, that the difference only exists, if i is declared outside >>> of the loop, that is, this is solely about the behavior after exiting the >>> loop-body. >>> >>> I'd greatly appreciate some explanation :) >> An attempt to explain this by looking at the C-style loop only: >> >> The classic C-style for loop >> >> for i:=0; i<len(v); i++ {...} >> >> is equivalent to >> >> for i:=0; i<len(v); { >> // do something with i >> i++ // This is always the very last statement in the loop body >> } >> >> The loop body runs from 0 to len(v)-1 only, because the last increment of i >> to len(v) stops the loop, and no further iteration occurs. The code in the >> loop body never sees i being set to len(v). >> >> And that's the same behavior as with the range operator. >> >> The code in the Reddit post takes advantage of the fact that the last >> increment of the C-style loop can be observed outside the loop, for >> detecting if the loop stopped early. This is a neat side effect that is not >> possible with the range operator. > > I would point out that both Axel and you are off a tiny bit from what > actually happens ;-) > > In a for loop which uses a short variable declaration, that variable's > scope is confined to the for *statement* itself, and is also visible in > the loop's body because its scope is defined to be nested in that of the > loop statement. This means in a loop like > > for i := 0; i < len(s); i++ { > } > > the variable "i" is not accessible after the closing brace. > > The actual "problem" stated in that Reddit post is different: it uses a > variable defined outside the "for" loop: > > var i int > for i = 0; i < len(v); i++ { > } > > As you can see, the loop merely uses that variable; it existed before > the loop and continued to live on after it finished executing. > > To recap what others have already written, since the for loop's post > statement is defined to be executed after each execution of the body > (unless it was exited by means of executing `break` or `return`), that > > i++ > > statement gets executed, the condition evaluates to false, and the loop > exits -- with the variable "i" having the value equal to len(v). > > One could do > > var x int > > for i := 0; i < len(v); i, x = i+1, x*2 { > } > > and get even more interesting effect on the variable "x" after the loop > finishes executing ;-) > > -- > You received this message because you are subscribed to a topic in the Google > Groups "golang-nuts" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/golang-nuts/Xi6W3H5mlto/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.