9. `for`: the only loop
Most languages have for, while, do-while, and a few more. Go has
one loop keyword — for — and it wears all those hats. Learn its four
shapes and you've learned every loop in the language.
1. The classic three-part for
for init; condition; post { ... } — set up, test before each pass, and run
a step after each pass:
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Println("i is", i)
}
}
i++ increments i by one. (Go has ++ and --, but they're statements,
not expressions — you can't write x := i++.) As always: no parentheses,
mandatory braces.
2. for as a "while" loop
Drop the init and post parts, keep just a condition, and for behaves like
a while:
package main
import "fmt"
func main() {
n := 1
for n < 100 {
n = n * 2
}
fmt.Println("first power of two >= 100:", n)
}
3. The infinite loop
No condition at all means loop forever — you exit with break (or return).
This is the standard shape for "keep going until something happens":
package main
import "fmt"
func main() {
count := 0
for {
count++
if count == 3 {
break // jump out of the loop entirely
}
}
fmt.Println("broke out at", count)
}
break leaves the loop. Its partner continue skips the rest of the
current pass and jumps to the next one:
package main
import "fmt"
func main() {
// print only the odd numbers under 10
for i := 0; i < 10; i++ {
if i%2 == 0 {
continue // even → skip to the next i
}
fmt.Print(i, " ")
}
fmt.Println()
}
4. for ... range
The fourth shape iterates over a collection — a slice, a map, a string. We'll meet slices and maps properly soon, but here's the shape so it's familiar:
package main
import "fmt"
func main() {
names := []string{"Ada", "Grace", "Katherine"}
for index, name := range names {
fmt.Printf("%d: %s\n", index, name)
}
}
range hands you two values each pass: the index and the value.
Don't need the index? Use the blank identifier _ to ignore it — remember,
an unused variable is a compile error, and _ is how you say "I don't want
this one":
package main
import "fmt"
func main() {
names := []string{"Ada", "Grace", "Katherine"}
for _, name := range names {
fmt.Println(name)
}
}
Since Go 1.22 you can also range over a plain integer to repeat N times.
It's a newer convenience the in-browser interpreter doesn't support yet, so
this box is reference-only — but it compiles and runs on any recent Go:
for i := range 3 {
fmt.Println("pass", i) // prints pass 0, pass 1, pass 2
}
Until then, the classic for i := 0; i < 3; i++ does the exact same job and
runs everywhere.
Loops nest
A loop inside a loop — the outer runs once for each full pass of the inner:
package main
import "fmt"
func main() {
for row := 1; row <= 3; row++ {
for col := 1; col <= 3; col++ {
fmt.Printf("%d ", row*col)
}
fmt.Println()
}
}
Your turn
Sum the integers from 1 to 100 (inclusive) in a loop and print exactly:
Sum 1..100 = 5050
package main
import "fmt"
func main() {
sum := 0
// loop from 1 to 100, adding each to sum
fmt.Printf("Sum 1..100 = %d\n", sum)
}
package main
import "fmt"
func main() {
sum := 0
for i := 1; i <= 100; i++ {
sum += i
}
fmt.Printf("Sum 1..100 = %d\n", sum)
}
Next: a cleaner way to branch many ways — switch.