Basic

Loops and Iteration

Repeat work with Go's only loop keyword, for.

What you will see

0 1 2 4

About 2 min of reading

Try It

Go has one loop keyword, for, and it replaces the while and do-while of other languages. You will count with three parts, walk a slice with range, and control the flow with break and continue.

1

I write a classic for loop with three parts inside the parentheses: init, condition, and post. Go prints the counter each time until the condition stops being true.

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

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0 1 2 3 4
The three parts are separated by semicolons, which stay even if you leave some empty. The condition is checked before each iteration.
2

I iterate a slice with range, which hands me both the index and the value on every pass. I print them together to see position and item line up.

package main import "fmt" func main() { fruits := []string{"apple", "banana", "cherry"} for i, f := range fruits { fmt.Println(i, f) } }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0 apple 1 banana 2 cherry
range works on slices, maps, arrays, and strings. For a map it yields key and value instead of index and value.
3

I use the blank identifier to ignore the index when I only want the values. Printing just the fruit name shows the shorthand, which Go calls _.

package main import "fmt" func main() { fruits := []string{"apple", "banana", "cherry"} for _, f := range fruits { fmt.Println(f) } }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
apple banana cherry
Use the blank identifier `_` to discard a value you will not use. It must be unnamed, never given a real name you never touch.
4

I show the bare for loop with no parts, the Go stand-in for while. I manage the counter myself and let the condition decide how long the loop runs.

package main import "fmt" func main() { i := 0 for i < 3 { fmt.Println(i) i++ } }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0 1 2
A bare for is the while loop of other languages. Forgetting to advance the counter makes an infinite loop, which you then exit with break.
5

I use continue to skip a value without leaving the loop. The loop still runs its full count, but it prints nothing for the skipped index.

package main import "fmt" func main() { for i := 0; i < 5; i++ { if i == 3 { continue } fmt.Println(i) } }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0 1 2 4
continue jumps back to the post step of a for loop. To skip the rest of an iteration in a different loop style, the keyword is the same.

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

A loop repeats a block; range yields each element with its position.
1 Initialize the loop counter
↓
2 Check the condition
↓
3 Execute the body
↓
4 Increment and repeat until condition fails
Why this works
The three parts of for

A for loop has init, condition, and post:

for init; condition; post {
    // body
}

  • init runs once before the loop
  • condition is checked before each iteration
  • post runs after each iteration

Any part can be omitted (but the semicolons stay).

range semantics

range is the idiomatic way to iterate:

for index, value := range collection {
    // ...
}

The index is the position; the value is a copy for value types. For strings, range iterates by rune (Unicode code point), so multi-byte characters are handled correctly.

Examples

Classic for loop

Counting loops

for i := 0; i < 5; i++ {
    fmt.Println(i)
}

Go has only one loop keyword: for. It has three parts, init, condition, **post*: all inside the parentheses.

Why it works: the condition is checked before each iteration; when it is false, the loop ends.

Range over slices

Iterating data

fruits := []string{"apple", "banana", "cherry"}
for i, f := range fruits {
    fmt.Println(i, f)
}

range gives you both the index and the value. Use _ to ignore the index:

for _, f := range fruits {
    fmt.Println(f)
}

range works on slices, strings, maps, and arrays.

Infinite loops

While-style loops

for {
    doThing()
    if done {
        break
    }
}

A bare for {} runs forever. Use break to exit. continue skips to the next iteration. Go's for replaces the while and do-while of other languages.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Conditionals and Branching
Previous Lesson
Conditionals and Branching
Next Lesson
Functions
Functions →