Range in Go works pretty much exactly the same as 'for in' in python and
the similar 'for each' construct in Java or the same construct in pretty
much every other language that has it.
If you could take the address of things in python or Java you'd notice
the same thing. It's the only efficient way to do such a construct and
it's pretty easy to understand.
- jessta
for i := range a {
a[i].foo = bar
}
For example:
----
package main
func main() {
a := make([]int, 4)
for i, v := range a {
println(&v, &a[i])
}
}
----
prints
----
0x7fee85916f44 0xf8400020f0
0x7fee85916f44 0xf8400020f4
0x7fee85916f44 0xf8400020f8
0x7fee85916f44 0xf8400020fc
----
Oh, and a newbie nit on Go terminology: []int is a slice, [4]int is an array.
You got only one response in two hours because it's the holiday season
in many parts of the world, and because it's a mailing list, not IRC.
And I don't read Jessta's response as saying any of baseless, stupid
or foolish.
The point is simply that Go structs behave like C structs and not like
Java objects, for things like assignment. If your prior experience is
C, then it is perfectly intuitive. If your prior experience is Java,
then some things will simply be different.
It would be great to have "Go for experienced Java programmers" or "Go
for experienced Python programmers" documentation, but I don't have
time to write it. I was surprised to find out that a[i:] and a[:j]
mean similar things in Python and Go, but a[:] means something totally
different. As a Go programmer, I found Python's behavior surprising.
I'm sure that an experienced Python programmer would have found Go's
behavior surprising. But I wouldn't call either myself or my
Python-loving friend stupid. We simply come from different
backgrounds.
Before going further, **my point here is that in learning Go, I got
tripped up by behavior that wasn't what I expected**, it may in fact
be good and reasonable and consistent with other principles, but maybe
we can do more to help people understand and make those things clear.
Except that in Python and Java all Objects are reference variables.
// Java:
for (MyClass x : arrayOfMyClass) {
x.foo = bar; // fine
}
// Go:
var arrayOfMyStruct []MyStruct
for i, x := range arrayOfMyStruct {
x.foo = bar // doom. useless assignment to local variable x.
}
The confusion comes from misunderstanding that aspect. What you get as
a value of iterations, parameters of functions, etc, is consistently a
_copy_ in most languages [1]. The question is just what is being
copied, not whether it is being copied or not. E.g.:
In Go:
for _, x := range []int{1,2,3} {} // x is a copy of the integer
for _, x := range []*int{a, b, c} {} // x is a copy of the pointer
to the integer value
for _, x := range []*T{d, e, f} {} // x is a copy of the pointer
to the T value
for _, x := range []T{g, h, i} {} // x is a copy of the T value
In Python:
for x in [1, 2, 3]: ... // x is a copy of the pointer (!) to the
integer object
for x in [a, b, c]: ... // x is a copy of the pointer (!) to each
object in the list
It's easy to miss the fact that e.g. Python works with pointers all
the time because we don't see the star there, but it's a fact: for
good and for bad, you're dealing with pointers all the time, even for
simple things such as integers [2]:
>>> a, b = int(1e9), int(1e9)
>>> object.__repr__(a); object.__repr__(b)
'<int object at 0xb47570>'
'<int object at 0xb475b8>'
>>> for i in [a, b]: object.__repr__(i)
...
'<int object at 0xb47570>'
'<int object at 0xb475b8>'
[1] Reference parameters in C++ being one of the notable and ugly
exceptions. http://j.mp/tNtKGQ
[2] PyPy and psyco are able to JIT-optimize them, though
--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/plus
http://niemeyer.net/twitter
http://niemeyer.net/blog
-- I'm not absolutely sure of anything.
It's still very much a gotcha if you come from other languages, I
think that stressing that the range operator is not just an
alternative way to write the "naive" loop on the index is well worth
half a sentence in the specs (or elsewhere).(eg, "as a result the
element of the array is a copied in the variable even if it's a
struct")
Aside from that I wonder if there is a way to loop on a map that
doesn't involve copying the elements of the map.
hmm I guess using _ for the element can do the trick
What would be great is if I could do something like:for _, &foo := range foos { ... }and get a pointer instead, but I haven't seen a way to do this (I could be missing something).
--
Consider:type Foo struct {bar *Bar}type Bar struct {value int}You do:foos []Foo := ...for _, foo := range foos {foo.bar.value = nextValue();}Now this work just fine & dandy until someone decides that Bar (being a small struct) can be inlined in Foo.type Foo struct {bar Bar}Now everything breaks! Remember that this code change will not require anyone to revisit the code in the for loop, which could be in another class/package altogether (in C++ you'd at least have to turn a '->' into a '.' to get it to compile again).
What would be great is if I could do something like:for _, &foo := range foos { ... }and get a pointer instead, but I haven't seen a way to do this (I could be missing something).
for i := range foos {
foo := &foos[i]
...
}
--
I'd prefer:
for _, &p := range stuff {
p.fieldName = 7
}
which I think is unambiguous syntactically.
David
--
David Beaumont :: Îñţérñåţîöñåļîžåţîờñ Libraries :: Google
Google Switzerland GmbH., Brandschenkestrasse 110, CH-8002, Zürich - Switzerland
Tel +41 44 668 1800 :: Fax +41 44 668 1818
Maybe that too, though it's a bit ambiguous when you have maps:
It'd be nice to say:
for k, &v := range myMap { ... }
David
--
David Beaumont :: Îñţérñåţîöñåļîžåţîờñ Libraries :: Google
Google Switzerland GmbH., Brandschenkestrasse 110, CH-8002, Zürich - Switzerland
Tel +41 44 668 1800 :: Fax +41 44 668 1818
Actually this is interesting. I didn't realize that it would be a copy either.Let's say I'm performance conscious. Does the following code copy the value at each iteration step:for i,_ := range someArray { }Thank you.--
I was referring to the "_", is there any copy happening there and then that copy being discarded?
--
On Sep 27, 2012 1:09 AM, "DisposaBoy" <dispo...@dby.me> wrote:
> I write latter form in all cases because I find it.clearer.
which form?