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
package main import "fmt" func main() { for i := 1; i <= 5; i++ { fmt.Println("Count:", i) } }
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:
package main import "fmt" func main() { stock := 100 for stock > 0 { stock -= 30 } fmt.Println("Stock:", stock) }
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:
package main import "fmt" func main() { n := 0 for { n++ if n%2 == 0 { continue } if n > 7 { break } fmt.Println("Odd:", n) } }
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
package main import "fmt" func main() { fruits := []string{"apple", "banana", "cherry"} for i, fruit := range fruits { fmt.Println(i, fruit) } }
0 apple 1 banana 2 cherry
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".