Looping in Go
From: loop.go
1 package main 2 import "fmt" 3 4 func main() { 5 loops := 1 6 // while loop: 7 for loops > 0 { 8 fmt.Printf("\nNumber of loops?\n") 9 fmt.Scanf("%d", &loops) 10 // for loop 11 for i := 0 ; i < loops ; i++ { 12 fmt.Printf("%d ", i) 13 } 14 } 15 // Infinite loop 16 for { 17 // Explicitly terminated 18 break 19 } 20 }
In C, you have three kinds of loops, all with different syntax and overlapping semantics. Go manages to have more expressive loop semantics, but simple and uniform syntax.
Every loop in Go is a for statement. We’ll only look at the forms that mirror C loop constructs here. The form that iterates over a collection is explained in Chapter 5, Arrays and Slices.
The loop.go example shows the three types of general for loops in Go. The last one is the simplest. This is an infinite loop, with an explicit break statement to terminate it. You’d most commonly use this form for an event loop that would not terminate in normal use. Like C, Go also has a continue statement that immediately jumps to the start of the next loop iteration, or exits the loop if the loop condition no longer holds.
Both the break and continue statements support an optional label for jumping out of nested loops. Note that the label is not a jump target; it is just used to identify the loop.
From: break.go
5 for i := 0 ; i<10 ; i++ { 6 L: 7 for { 8 for { 9 break L 10 } 11 } 12 fmt.Printf("%d\n", i) 13 }
You can see this in the break.go example. The break statement jumps out of the two inner loops, but does not prevent the Printf call from running. It jumps to the end of the loop immediately after L:, not to the start.
Most of the time, you won’t use infinite loops and explicit escapes. The other two types of for loops in Go are analogous to while and for loops in C and the older form of for loops in Java. The outer loop in the example at the start of this section will test its condition and loop as long as it is true. The inner loop first performs the initialization (i := 0) then tests the loop condition (i < loops), and runs the loop clause as long as it’s true. Between each loop iteration, it runs the increment clause (i++). If you’ve used any vaguely C-like language, then this will be very familiar to you. The only difference between a Go for loop and a C for loop is that the Go version does not require brackets.
There are a couple of interesting things in this loop. The first is the creation of the loop variable (i) at the loop scope. This is similar to C99 or C++. The variable that is declared in the loop initialization clause is only in scope for the duration of the loop.
The second is the increment statement. Note that I did not call it a postincrement expression. The designers of Go decided to eliminate the confusion between preincrement and postincrement expressions in C. In Go, the increment statement is not an expression, and only the suffix syntax is allowed. This line increments the variable, but it does not evaluate to anything. Writing something like a := b++ is not valid Go. Writing ++b is invalid in all contexts in Go: there is no prefix form of the operator.