Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignoring values in Go's range

Tags:

I have a question about Go's range and the way in which ignoring return values work.

As the documentations stands, each iteration, range produces two values - an index and a copy of the current element, so if during an iteration we want to change a field in the current elmenet, or the element itself we have to reference it via elements[index], because elment is just a copy (assuming that the loop looks something like this for index, element := range elements).

Go also allows to ignore some of the return values using _, so we can write for index, _ := elements.

But it got me thinking. Is Go smart enough to actually don't make a copy when using the _ in range? If it isn't, then if elements in elements are quite big and we have multiple processes/go-routines running our code, we are wasting memory, and it would be better to use looping based on len(elements).

Am I right?

EDIT

We can also use

for index := range elements

which seems like a good alternative.

like image 888
wookie Avatar asked Mar 09 '18 10:03

wookie


1 Answers

The for range construct may produce up to 2 values, but not necessarily 2 (it can also be a single index value or map key or value sent on channel, or even none at all).

Quoting from Spec: For statements:

If the range expression is a channel, at most one iteration variable is permitted, otherwise there may be up to two.

Continuing the quote:

If the last iteration variable is the blank identifier, the range clause is equivalent to the same clause without that identifier.

What this means is that:

for i, _ := range something {}

Is equivalent to:

for i := range something {}

And another quote from Spec: For statements, a little bit down the road:

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.

So the extra blank identifier in the first case does not cause extra allocations or copying, and it's completely unnecessary and useless.

like image 56
icza Avatar answered Nov 15 '22 03:11

icza