-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: Go 2: add &range in for statements #21537
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Why do you need to take an address? What's wrong with this? for i := range a {
a[i].DoSomething()
} |
@pcostanza avoiding writing a few characters or a line (in this case, It's also worth noting that Go always passes by value - if you want to modify something, you pass its pointer. Adding |
There are situations where you need to refactor your code, and one potential refactoring is to store structs as values in slices rather than pointers to structs. If then, in a corresponding for loop, you need to refer to the single entries by address rather than by value, you would have to move from (1) to (2):
With the proposed change, such refactorings would be easier and result in more elegant code IMHO. The alternative you're suggesting is to replace each occurrence of
I don't particularly care about the concrete syntax. The idea of Other possible syntaxes could be
I'd guess that's probably more problematic though from a language specification point of view, though. Again, I don't care about the particular syntax, but i think the feature could improve the language and make it a bit more orthogonal. (The |
Note that my point about passing by value has little to do with syntax. With the current state of things, you have to explicitly take the address via I see your point about the extra verbosity, but I'm still not (personally) convinced. Could you elaborate on your error-prone point? |
Related: #8346 |
I really like this suggestion. I've worked on quite a bit of code that uses []T rather than []*T for performance reasons and it's awkward to need to explicitly index into the slice rather than being able to use an iteration variable. I also agree that it's error-prone: when you're using such slices it's easy to accidentally write |
OK, now I see what you mean. I still disagree with you, though. In C++, you indeed regularly encounter situations where the address of an object is implicitly taken, just by virtue of calling a function that takes reference parameters. There is no syntactic clue whatsoever at the call site that this is happening, and I fully understand that you want to avoid adding features that could lead to similar situations. However, my proposal doesn't do this: The expression that specifies which values addresses are taken of is right next to the
Nothing special here: The more code you need to touch in a refactoring, the more opportunities there are for making mistakes, like typing |
I have sentiment for the general idea; the situation where one wants to iterate over the addresses rather than the elements of an array/slice does occur fairly often, and it's unsatisfying that that code has to be quite asymmetric compared to the case where one iterates over the elements. A couple of observations:
(suggested in #21537 (comment)) would be problematic because the same notation using a
I don't know if 2) would be a show stopper, but at the very least it's going to be a concern that speaks against the proposal. |
I believe this is only an issue when refactoring code from using a slice representation to a map representation, or vice versa, for a particular use case. However, such a refactoring requires much deeper changes than adapting a few for loops, so there is no need to create the illusion it's an easy change in the for loops. (It would be nicer, indeed, but won't be the major refactoring challenge.) Moving from |
I like the idea and spoke of it in the mailing list a few years ago. one of the proposals from another person on that thread (Gri?) was a three-value range, with index, value, and pointer to value as the result. In this scenario, the existing two-value case is extended but the third value could be generally ignored. When the pointer was wanted, "i,_,p := range ..." gives it to you. that seemed ok to me. |
This new syntax is occasionally convenient, but it only works for slices and arrays, not for strings, maps, or channels. It's a fairly minor bit of syntactic sugar, and it doesn't seem to bring enough benefit for the cost of making the range statement even less consistent. |
When using the for statement to loop over a slice, it is sometimes useful or necessary to take the address of each slice entry rather than a value copy. However, doing this is a bit inconvenient and could be made more readable.
Loop over a slice by value:
Loop over a slice by address:
Proposed syntactic extension to loop over a slice by address:
I believe the suggested extension is more readable and makes the intent clearer.
The text was updated successfully, but these errors were encountered: