1 min read
Range conclusion
Today we finish up with some final notes, and a big example, from the spec section on for statements. For statements with range clause … If the iteration variables are not explicitly declared by the “range” clause, they must be preexisting. In this case, the iteration values are assigned to the respective variables as in an assignment statement. I actually discussed this case yesterday, so won’t go into it again.
2 min read
Scope and type of range variables
For statements with range clause … The iteration variables may be declared by the “range” clause using a form of short variable declaration (:=). In this case their scope is the block of the “for” statement and each iteration has its own new variables [Go 1.22] (see also “for” statements with a ForClause). We’ve already talked at some length about the scope of variables in other forms of for loops.
1 min read
Iteration over integers
I’m back from my holiday! I thought I’d send at least a few dalies over the last week while I was on vacation, but it wasn’t meant to be. But now that I’m back, we’ll pick up where we left off… For statements with range clause … For an integer value n, the iteration values 0 through n-1 are produced in increasing order. If n <= 0, the loop does not run any iterations.
2 min read
Iteration over channels
Two quick related notes: I missed a day or two last week, due to travel. I’lll be traveling through the middle of next week as well, so these “daily” emails may be slightly less frequent. We’ll see. And related to that, no live stream this week or next. I expect to live stream again July 8. Hope to see you then! For statements with range clause … For channels, the iteration values produced are the successive values sent on the channel until the channel is closed.
2 min read
Iteration over maps
For statements with range clause … The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. If a map entry that has not yet been reached is removed during iteration, the corresponding iteration value will not be produced. If a map entry is created during iteration, that entry may be produced during the iteration or may be skipped.
3 min read
Iteration over strings
For statements with range clause … For a string value, the “range” clause iterates over the Unicode code points in the string starting at byte index 0. On successive iterations, the index value will be the index of the first byte of successive UTF-8-encoded code points in the string, and the second value, of type rune, will be the value of the corresponding code point. If the iteration encounters an invalid UTF-8 sequence, the second value will be 0xFFFD, the Unicode replacement character, and the next iteration will advance a single byte in the string.
2 min read
Iteration over arrays and slices
For statements with range clause … 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. From this above paragraph, we can be assured that ranging over an array, pointer to array, or slice, will operate in a defined order–from index 0, upward.
Subscribe to Boldly Go: Daily
Every day I'll send you advice to improve your understanding of Go. Don't miss out! I will respect your inbox, and honor my privacy policy.
Unsure? Browse the archive.
2 min read
The types of iteration variables
For statements with range clause … For each iteration, iteration values are produced as follows if the respective iteration variables are present: Range expression 1st value 2nd value array or slice a [n]E, *[n]E, or []E index i int a[i] E string s string type index i int see below rune map m map[K]V key k K m[k] V channel c chan E, <-chan E element e E integer n integer type value i see below How do we read this table?
1 min read
Functions on the left-hand side of a for-range statement
For statements with range clause … Function calls on the left are evaluated once per iteration. This small sentence is easy to overlook. What does it mean? It means if you have any function calls on the left hand side of the for range statement, they are executed per iteration. What would that even look like? It’s probably a rare occurrence, but here’s an example in the playground: func main() { for _, m()["foo"] = range []string{"foo", "bar", "baz"} { } fmt.
2 min read
Evaluation of range expressions
For statements with range clause … The range expression x is evaluated once before beginning the loop, with one exception: if at most one iteration variable is present and len(x) is constant, the range expression is not evaluated. The first part of this seems pretty self-evident, as it follows the same pattern as a for statement with a for clause: The expression needs to be evaluated once before the loop executes.
2 min read
For statements with range clause
Yesterday we saw some high-level examples of range statements. Let’s start into some of the details now. For statements with range clause … For each entry it assigns iteration values to corresponding iteration variables if present and then executes the block. RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression . The formal definition there is pretty straight forward. But there are a number of nuances, which we’ll cover over the next few days.