This is actually a really good point, thanks :) On Wed, Jul 26, 2017 at 1:37 AM, Chris Manghane <cm...@google.com> wrote:
> Hmm, well I can't give better reasoning off the top of my head, but I > still have to wonder why you expect the behavior of those constructs to be > the same, particularly. Imagine, you would like to capture both the > iteration variable and the value itself, for example: > > var i, v = 0, "" > for i, v = range someSlice {} > println(v) > > What is the value of `v`? I expect that the last elements of the iteration > of someSlice, namely len(someSlice) - 1 and someSlice[len(someSlice) - 1], > would be stored in `i` and `v`, respectively. Alternatively, I might > implement this as (or lower it to): > > var i, v = 0, "" > for i = 0; i <= len(someSlice); i++ { > v = someSlice[i] > } > > With the alternative implementation, it seems like either the value in `v` > would be completely invalid (or cause an out-of-bounds error) or there > would be a mismatch between the value that `i` and `v` stop at after > iteration. I'm not sure if that's official reasoning, but the semantics of > range statements are different in many other situations as well so it seems > consistent to me. > > On Tue, Jul 25, 2017 at 4:11 PM, Axel Wagner < > axel.wagner...@googlemail.com> wrote: > >> On Wed, Jul 26, 2017 at 12:52 AM, Chris Manghane <cm...@google.com> >> wrote: >> >>> This is mentioned directly in the language specification under For >>> statements with range clause <https://golang.org/ref/spec#For_range>: >>> >>> For each entry it assigns iteration values to corresponding iteration >>>> variables if present and then executes the block. >>> >>> and >>> >>>> For an array, pointer to array, or slice value a, the index iteration >>>> values are produced in increasing order, starting at element index 0. If at >>>> most one iteration variable is present, the range loop produces iteration >>>> values from 0 up to len(a)-1 and does not index into the array or slice >>>> itself. For a nil slice, the number of iterations is 0. >>> >>> >>> This seems logically correct to me, as well. For an array or slice of >>> len(array) = N, the for range statement generates N iteration values, >>> starting from 0. The Nth iteration value would have to be N-1. The >>> difference in semantics is because the post statement in a for loop must be >>> executed after the body is executed. A typical for-loop assigns the N+1st >>> iteration value to the iteration variable, but that is a user's choice. >>> >>> Hopefully that is more clear, >>> >> >> Not really, sorry :) You basically reiterated the status quo, but did >> hardly explain *why* those choices where actually made. >> >> > For an array or slice of len(array) = N, the for range statement >> generates N iteration values, starting from 0. The Nth iteration value >> would have to be N-1. >> >> That would also be the case if the loop would be equivalent to the >> obvious for-loop in regards to indices. >> >> > he difference in semantics is because the post statement in a for loop >> must be executed after the body is executed. >> >> Well, yeah, the question is, why wasn't this also done for range. Or >> rather, why wasn't the range of indices assigned decided to be equivalent >> with the most obvious for-loop. >> Especially as it seems, that if you use :=, the generated code actually >> *does* seem to include the extra increment (bringing the index to len(v), >> even if unobservably), so pure efficiency does not seem to be the reason. >> >> The reason for the decision might very well be "someone just decided it >> that way and now that's the way it is". That'd be fine. I'd just be >> interested to know if there was a more deliberate reasoning behind this. >> >> >> >>> Chris >>> >>> On Tue, Jul 25, 2017 at 3:30 PM, 'Axel Wagner' via golang-nuts < >>> golang-nuts@googlegroups.com> wrote: >>> >>>> Hey, >>>> >>>> someone shared [this question](https://www.reddit.c >>>> om/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 :) >>>> >>>> -- >>>> 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. >>>> >>> >>> >> > -- 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.