Skip to main content
The for loop is the sole iterative control flow statement in Go. It unifies the behavior of traditional for and while loops found in other C-family languages into a single keyword. Go achieves this by overloading the for statement with four distinct syntactic forms.

1. The Three-Component Loop

This is the standard C-style loop, consisting of an initialization statement, a boolean condition, and a post-iteration statement.
for init; condition; post {
    // loop body
}
  • init: Executed once before the loop begins. Variables declared here using the short variable declaration (:=) are lexically scoped to the loop block. As of Go 1.22, these variables are scoped per-iteration rather than per-loop, meaning each iteration creates a distinct instance of the variable.
  • condition: A boolean expression evaluated before every iteration. If it evaluates to false, the loop terminates.
  • post: Executed immediately after each iteration of the loop body, prior to the next condition evaluation.
Note: Unlike C or Java, Go does not wrap the three components in parentheses, but the braces {} surrounding the body are mandatory.

2. The Condition-Only Loop

By omitting the init and post statements, the for loop functions identically to a traditional while loop. The semicolons are dropped in this form.
for condition {
    // loop body
}
The loop continues to execute as long as the condition evaluates to true.

3. The Infinite Loop

Omitting all three components creates an infinite loop.
for {
    // loop body
}
Execution will continue indefinitely unless interrupted by a loop control statement (e.g., break, return, or a panic).

4. The For-Range Loop

The for range construct is used to iterate over elements of iterable data structures, integers, and iterator functions.
for key, value := range iterable {
    // loop body
}
The range clause yields zero, one, or two iteration variables depending on the underlying type:
  • Arrays/Slices: Yields the index (int) and a copy of the value at that index.
  • Strings: Yields the byte index (int) and the Unicode code point (rune).
  • Maps: Yields the key and a copy of the value. Iteration order is intentionally randomized.
  • Channels: Yields only the value received from the channel until the channel is closed.
  • Integers (Go 1.22+): Yields an integer from 0 up to, but not including, the specified integer (e.g., for i := range 10).
  • Iterator Functions (Go 1.23+): Yields values from functions matching standard iterator signatures (e.g., iter.Seq or iter.Seq2).
If an iteration variable is not required, it must be explicitly discarded using the blank identifier (_). Alternatively, the second variable can be omitted entirely if only the first is needed (for key := range iterable). Both variables can also be omitted entirely if the loop only needs to execute a specific number of times without referencing the yielded values (for range iterable { ... }). Similar to the three-component loop, variables declared with := in a range clause are scoped per-iteration as of Go 1.22.

Loop Control Statements

Go provides specific statements to alter the standard execution flow of a for loop:
  • break: Immediately terminates the execution of the innermost enclosing for, switch, or select statement.
  • continue: Halts the current iteration, skips the remaining body, executes the post statement (if applicable), and proceeds to the next condition evaluation.
  • Labels: Both break and continue can be followed by an optional label to target a specific outer loop in nested loop architectures.
OuterLoop:
for i := 0; i < 5; i++ {
    for j := 0; j < 5; j++ {
        if i == 2 && j == 2 {
            break OuterLoop // Terminates the loop labeled 'OuterLoop'
        }
    }
}
Tired of Poor Go Skills? Fix That With Deep Grasping!Learn More