
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.

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.
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
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.

2 min read
Rangeable values
For statements with range clause A “for” statement with a “range” clause iterates through all entries of an array, slice, string or map, values received on a channel, or integer values from zero to an upper limit [Go 1.22]. Wow, that’s a long list. And it’s about to get longer! Go 1.23 is scheduled to add iterator functions to that list, but we’ll talk about that when the time comes (in August).

2 min read
Final notes on for loop variable scope
For statements with for clause … The variable used by the first iteration is declared by the init statement. The variable used by each subsequent iteration is declared implicitly before executing the post statement and initialized to the value of the previous iteration’s variable at that moment. So let’s break this down. In fact, the pseudo code I showed you during my earlier breakdown really more closely demonstrated the behavior prior to Go 1.

2 min read
Unique loop variables and the Go 1.22 fix
If you haven't joined me for a livestream in the past, consider [joining today](https://youtube.com/live/BYOsoZ5ywx8)! I'll be doing some refactoring, and adding new features to [Kivik](https://kivik.io/), with TDD. For statements with for clause … Each iteration has its own separate declared variable (or variables) [Go 1.22]. This seemingly simple sentence carries a lot of weight. So that’s what we’ll be talking about today. Prior to Go 1.22 (which only came out earlier this year!

2 min read
Omitting for clause elements
For statements with for clause … Any element of the ForClause may be empty but the semicolons are required unless there is only a condition. If the condition is absent, it is equivalent to the boolean value true. for cond { S() } is the same as for ; cond ; { S() } for { S() } is the same as for true { S() } So this goes to show that the single condition form of the for loop is really just a special case of the “for clause” for loop, with the init and post statements omitted.

2 min read
For statements with for clause
Today we’ll look at the second, of three, types of for statements: Those with a for clause. For statements with for clause A “for” statement with a ForClause is also controlled by its condition, but additionally it may specify an init and a post statement, such as an assignment, an increment or decrement statement. The init statement may be a short variable declaration, but the post statement must not. ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .