The Golang for loop is a fundamental control structure that makes Go programming both powerful and elegant. In this comprehensive guide, we’ll explore the different ways to use for loops in Golang, from basic iteration to more advanced patterns that every Go developer should master.
The Basic Golang For Loop Syntax
The standard Golang for loop has a clean syntax that will feel familiar to developers coming from C-style languages:
// Basic for loop with a single condition
func main() {
for i := 0; i < 5; i++ {
fmt.Println("Iteration:", i)
}
}
This is equivalent to a traditional for
loop in other languages. The three components are:
- Initialization:
i := 0
- Condition:
i < 5
- Post statement:
i++
While-Style Golang For Loops
Unlike many languages, Golang doesn’t have a separate while
keyword. Instead, the Golang for loop can act as a while loop by using just a condition:
// While-like loop
func main() {
count := 0
for count < 5 {
fmt.Println("Count:", count)
count++
}
}
Infinite Golang For Loops
To create an infinite loop in Golang, simply use the for
keyword without any conditions:
// Infinite loop
func main() {
for {
fmt.Println("This will run forever")
time.Sleep(1 * time.Second)
}
}
Range-Based Golang For Loops
One of the most common patterns in Golang is using the for
loop with range
to iterate over collections:
Iterating Over Slices and Arrays
func main() {
fruits := []string{"apple", "banana", "cherry"}
// Using range with index and value
for index, fruit := range fruits {
fmt.Printf("Index: %d, Fruit: %s\n", index, fruit)
}
// If you only need the value
for _, fruit := range fruits {
fmt.Println(fruit)
}
// If you only need the index
for i := range fruits {
fmt.Println("Index:", i)
}
}
Iterating Over Maps
func main() {
userRoles := map[string]string{
"alice": "admin",
"bob": "user",
"eve": "editor",
}
for key, value := range userRoles {
fmt.Printf("%s is an %s\n", key, value)
}
}
Iterating Over Strings
func main() {
str := "Hello, 世界"
// By bytes
for i := 0; i < len(str); i++ {
fmt.Printf("%x ", str[i])
}
fmt.Println()
// By runes (Unicode code points)
for _, r := range str {
fmt.Printf("%c ", r)
}
fmt.Println()
}
Controlling Golang For Loop Flow with Break and Continue
Using Break
func main() {
for i := 0; i < 10; i++ {
if i == 5 {
break // Exit the loop when i is 5
}
fmt.Println(i)
}
// Breaking out of nested loops with labels
outer:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if i*j > 2 {
fmt.Println("Breaking outer loop")
break outer
}
fmt.Printf("%d*%d=%d\n", i, j, i*j)
}
}
}
Using Continue
func main() {
for i := 0; i < 5; i++ {
if i%2 == 0 {
continue // Skip even numbers
}
fmt.Println("Odd:", i)
}
}
Common Golang For Loop Patterns
Processing Channels
func main() {
ch := make(chan int)
// Producer
go func() {
defer close(ch)
for i := 0; i < 5; i++ {
ch <- i
}
}()
// Consumer
for num := range ch {
fmt.Println("Received:", num)
}
}
Time-Based Loops
func main() {
// Run every second for 5 seconds
timeout := time.After(5 * time.Second)
tick := time.Tick(1 * time.Second)
for {
select {
case <-timeout:
fmt.Println("Timeout!")
return
case t := <-tick:
fmt.Println("Tick at", t)
}
}
}
Golang For Loop Performance Considerations
- Pre-allocate slices when you know the final size to avoid reallocations.
- Reuse buffers when processing large datasets.
- Be careful with append in loops as it may cause multiple allocations.
- Consider concurrency for CPU-bound operations using goroutines.
Conclusion
The Golang for loop is a versatile construct that can handle all your iteration needs. Whether you’re working with collections, channels, or need precise control over loop execution, Golang provides a clean and efficient way to express your logic. By understanding these patterns and best practices, you’ll be able to write more idiomatic and performant Go code.
Remember that while for
is the only loop construct in Golang, its flexibility makes it suitable for all iteration scenarios you might encounter in your programs. Mastering the Golang for loop is an essential skill for any Go developer.