Loops

Go has exactly one looping keyword — for — and it covers every job that for, while, and do/while split up across in C, C++, C#, and Java.

for as a counting loop

Go main.go
package main

import "fmt"

func main() {
	for i := 1; i <= 5; i++ {
		fmt.Println("Count:", i)
	}
}
Output
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5

This looks almost identical to a C-style for loop, just without parentheses around the three parts (init, condition, post) — Go drops parens on control statements across the board.

for as a while loop

Drop the init and post parts, and for with just a condition behaves exactly like while in other languages:

Go main.go
package main

import "fmt"

func main() {
	stock := 100

	for stock > 0 {
		stock -= 30
	}
	fmt.Println("Stock:", stock)
}
Output
Stock: -20

for stock > 0 keeps subtracting 30 until the condition fails — after four iterations stock is -20, which is no longer greater than 0, so the loop stops.

Infinite loops, break, and continue

A bare for with no condition at all loops forever, until something inside it breaks out:

Go main.go
package main

import "fmt"

func main() {
	n := 0

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

continue skips straight to the next iteration for even numbers, and break exits the loop entirely once n passes 7 — without a break somewhere, a bare for like this never stops on its own.

for-range over a slice

Go main.go
package main

import "fmt"

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

	for i, fruit := range fruits {
		fmt.Println(i, fruit)
	}
}
Output
0 apple
1 banana
2 cherry
Note: for i, fruit := range fruits gives you the index and a copy of each element, not a reference to it. Writing fruit = "grape" inside the loop changes only that local copy — the original slice is untouched. To modify the slice itself while iterating, index into it directly with fruits[i] = "grape".