14.Loop - For Statement - Programming in GO

Posted on Mar 06, 2019   ∣  3 min read  ∣  GO

Loop - For Statement

Let’s have a look at For statements in the Go spec.

The for statement specifies repeated execution of a block. There are three forms: The iteration may be controlled by a single condition, a for clause, or a range clause.

ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .
Condition = Expression .

This is not valid Go syntax. It’s called Extended Backus–Naur form (EBNF). EBNF is used to talk about a computer language.

package main

import (
	"fmt"
)

func main() {
	x := 1
	for x < 10 {
		fmt.Println(x)
		x++
	}
	fmt.Println("done.")
}

playground

Continuing through the Go specification on for statements, we come to “For statements with for clause,” which looks like this:

for i := 0; i < 10; i++ {
	f(i)
}

The specification explains,

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.

Then, we have the EBNF explanation

ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .

If we relate this to the example above, i := 0 is the InitStmt, i < 10 is the Condition, and i++ is the PostStmt.

Now, if we continue through the specification, it says

The init statement may be a short variable declaration, but the post statement must not. Variables declared by the init statement are re-used in each iteration.

This further clarifies that the variable declared in the init statement is used in each iteration of the loop, and that we cannot have a short variable declaration in the post statment.

Continuing,

If non-empty, the init statement is executed once before evaluating the condition for the first iteration; the post statement is executed after each execution of the block (and only if the block was executed).

So, in the example the init statement i := 0 is executed first. Then the condition i < 10 is evaluated. Then, after the contents within the loop (the block) are executed, the post condition is executed.

Let’s take a look at another way we could iterate through a for loop, and break when we are done.

package main

import (
	"fmt"
)

func main() {
	x := 1
	for {
		if x > 9 {
			break
		}
		fmt.Println(x)
		x++
	}
	fmt.Println("done.")
}

playground

That’s an example of how we can use for on its own (without the init statement, condition, and post statement).

In addition to the Go Specification, another great resource for Go documentation is Effective Go. Let’s have a look at what it has to say about For

The Go for loop is similar to—but not the same as—C’s. It unifies for and while and there is no do-while. There are three forms, only one of which has semicolons.

// Like a C for
for init; condition; post { }

// Like a C while
for condition { }

// Like a C for(;;)
for { }

Notice how Effective Go jumps right to practical uses, whereas the Go Specification has a deeper explanation of the inner-workings. These two resources are excellent for diving into Go.