for in Go
Go has one loop: for. It covers classic, while-like, range, and infinite loops. Prefer range for readability; fall back to index loops when mutating slices.
Classic for
The C-style three-part header: init; condition; post. All parts are optional; declare the index inside the loop scope.
for i := 0; i < 3; i++ {
// ...
}
While-like
for i < n { /* ... */ }
Common for polling and read loops; ensure termination conditions to avoid infinite loops.
Infinite loop
for {
// break when done
if done { break }
}
Use with select in goroutines for servers and workers; always include a break/return path.
Range over collections
range iterates over elements of a variety of types, yielding index/key and value.
// slice
for i, v := range []int{10,20,30} { _ = i; _ = v }
// array
arr := [3]string{"a","b","c"}
for i, v := range arr { _ = i; _ = v }
// map (order not guaranteed)
m := map[string]int{"a":1, "b":2}
for k, v := range m { _ = k; _ = v }
// string (iterates runes)
for i, r := range "héllo" { _ = i; _ = r }
Notes:
- On slices/arrays,
vis a copy of the element; taking&vpoints to the loop variable, not the backing element - On maps, iteration order is randomized; don’t rely on it
- On strings,
iis byte offset andris a rune (Unicode code point)
Control flow
for i := 0; i < 10; i++ {
if i%2 == 0 { continue }
if i > 7 { break }
}
Labels allow breaking/continuing outer loops; use sparingly for clarity.
Labels (advanced)
Outer:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if i == j { continue Outer }
if i+j > 3 { break Outer }
}
}
Pitfalls
- Range over slice/map returns copies of values; if you need addresses, take care
- Modifying a slice while ranging may skip/duplicate elements; usually range over indices
- Map iteration order is random by design; do not rely on it
- Capturing loop variables in goroutines: pass
vas a parameter to avoid sharing the same variable
Patterns
// Range over indices (safe if mutating slice)
s := []int{1,2,3}
for i := range s {
s[i] *= 2
}
// Accumulate
sum := 0
for _, v := range s { sum += v }
// Find
idx := -1
for i, v := range s { if v == 4 { idx = i; break } }
Summary
- One looping construct, many forms
- Prefer
rangefor readability; use indices when mutating - Use labels sparingly; keep loops simple and clear
- Be careful with addresses of range variables and goroutine captures