Go Loops

Go simplifies iteration down to a single keyword, for, which is flexible enough to cover every looping pattern other languages split across for, while, and do-while.

The three-part for loop

The most familiar form of for has an init statement, a condition, and a post statement, separated by semicolons. The init runs once before the loop starts, the condition is checked before every iteration, and the post statement runs after every iteration. Notice that, just as with if, there are no parentheses around the clauses.

Classic counting loop

package main

import "fmt"

func main() {
	for i := 0; i < 5; i++ {
		fmt.Println("Iteration:", i)
	}
}

for as a while loop

Dropping the init and post statements leaves just a condition, which turns for into the equivalent of a while loop found in other languages. Go has no separate while keyword — this is the idiomatic replacement.

for used as a while loop

package main

import "fmt"

func main() {
	count := 0

	for count < 3 {
		fmt.Println("Count is", count)
		count++
	}
}

The infinite loop and break

Removing every clause produces for {}, an infinite loop that only ends when a break statement executes inside it, or when the enclosing function returns. This pattern is common for server loops, polling, or reading from a channel until a stop condition is met.

Infinite loop with break and continue

package main

import "fmt"

func main() {
	n := 0

	for {
		n++
		if n%2 == 0 {
			continue
		}
		if n > 7 {
			break
		}
		fmt.Println("Odd number:", n)
	}
}

Ranging over collections

The range form of for walks over the elements of a slice, array, map, string, or channel without needing to manage an index manually. Ranging over a slice or array yields an index and a copy of the value at that index; ranging over a map yields a key and value pair, though the order of map iteration is intentionally randomized by the runtime.

for-range over a slice

package main

import "fmt"

func main() {
	fruits := []string{"apple", "banana", "cherry"}

	for index, fruit := range fruits {
		fmt.Println(index, "->", fruit)
	}
}
  • for init; condition; post {} — the classic three-clause loop.
  • for condition {} — behaves like a while loop.
  • for {} — an infinite loop, exited with break.
  • for k, v := range collection {} — iterates over slices, arrays, maps, and strings.
  • Use the blank identifier _ to discard the index or value you do not need, e.g. for _, v := range fruits.
KeywordEffect
breakExits the loop immediately
continueSkips to the next iteration
Note: A labeled break or continue (like `outer:` before a loop) lets you control an outer loop from inside a nested one — useful when a simple break would only escape the inner loop.
Note: When ranging over a slice, the loop variable holding the value is a copy. Mutating it inside the loop body does not change the original slice element; index into the slice directly if you need to modify it.

Exercise: Go Loops

Which loop keywords does Go provide for iteration?