For Loops in Go
Table of Contents
For loops are a programmer's best friend! They allow us to execute blocks of code repeatedly and iterate over collections of items. In Go, there are several different ways to write one.
All the content from our Boot.dev courses are available for free here on the blog. This one is the "Loops" chapter of Learn Go. If you want to try the far more immersive version of the course, do check it out!
The Standard 3-Component Loop
The basic loop in Go is written in standard C-like syntax:
for INITIAL; CONDITION; AFTER {
// do something
}
INITIAL is run once at the beginning of the loop and can create variables within the scope of the loop.
CONDITION is checked before each iteration. If the condition doesn't pass then the loop breaks.
AFTER is run after each iteration.
For example:
for i := 0; i < 10; i++ {
fmt.Println(i)
}
// Prints 0 through 9
Go's loop syntax looks similar to that of C, Java, or JavaScript. The biggest difference is the simple lack of parentheses surrounding the components.
Omitting Conditions from a for Loop in Go
Loops in Go can omit sections of a for loop. For example, the CONDITION (middle part) can be omitted which causes the loop to run forever.
for INITIAL; ; AFTER {
// do something forever
}
Building on the idea of a flexible for-loop, we can omit the INITIAL or AFTER statements of the three-component loop as we please.
i := 0
for ; sum < 1000; i++ {
sum += i
}
for i := 0; sum < 1000; {
sum += i
i++
}
This can be a useful pattern when you want something like a do-while, or an immediate first tick from a ticker.
Omit all three components and you're left with an infinite loop:
for {
// do some stuff forever
}
Infinite loops are useful when you have a worker or process that need to run forever, like a web crawler.
There Is No While Loop in Go
Most programming languages have a concept of a while loop. Because Go allows for the omission of sections of a for loop, a while loop is just a for loop that only has a CONDITION.
for CONDITION {
// do some stuff while CONDITION is true
}
For example:
plantHeight := 1
for plantHeight < 5 {
fmt.Println("still growing! current height:", plantHeight)
plantHeight++
}
fmt.Println("plant has grown to ", plantHeight, "inches")
Which prints:
still growing! current height: 1
still growing! current height: 2
still growing! current height: 3
still growing! current height: 4
plant has grown to 5 inches
Range
I've found that I'm rarely using Go's standard loop syntax, because I'm usually looping over a collection of values. If you need to iterate over a map, slice, channel, or string, Go makes it easy with the range keyword.
Range over a slice in Go
Go provides syntactic sugar to iterate easily over elements of a slice:
for INDEX, ELEMENT := range SLICE {
}
The element is a copy of the value at that index.
For example:
fruits := []string{"apple", "banana", "grape"}
for i, fruit := range fruits {
fmt.Println(i, fruit)
}
// 0 apple
// 1 banana
// 2 grape
Range over a map in Go
ages := map[string]int{
"lane": 26,
"preston": 28,
"rory": 21,
}
for name, age := range ages {
fmt.Println(name, age)
}
// prints:
// lane 26
// preston 28
// rory 21
Range over a channel in Go
ch := make(chan int)
go func() {
for i := 0; i < 3; i++ {
ch <- i
}
close(ch)
}()
// loop ends when channel is close
for value := range ch {
fmt.Println(value)
}
fmt.Println("channel closed")
// prints:
// 0
// 1
// 2
// channel closed
Range over a string in Go
name := "lane"
for i, char := range name {
// cast the rune to a string for printing
fmt.Println(i, string(char))
}
// prints
// 0 l
// 1 a
// 2 n
// 3 e
Continue & Break
Whenever we want to change the control flow of a loop we can use the continue and break keywords.
continue
The continue keyword stops the current iteration of a loop and continues to the next iteration. continue is a powerful way to use the guard clause pattern within loops.
for i := 0; i < 10; i++ {
if i % 2 == 0 {
continue
}
fmt.Println(i)
}
// 1
// 3
// 5
// 7
// 9
break
The break keyword stops the current iteration of a loop and exits the loop.
for i := 0; i < 10; i++ {
if i == 5 {
break
}
fmt.Println(i)
}
// 0
// 1
// 2
// 3
// 4
Frequently Asked Questions
What are the three components of a for loop in Go?
The three components are INITIAL, CONDITION, and AFTER. INITIAL runs once, CONDITION is checked before each iteration, and AFTER runs after each iteration.
Does Go have a while loop?
No. A while loop in Go is a for loop that only has a condition.
How do you create an infinite loop in Go?
Omit the condition entirely and use for {}.
What does range return for a slice?
Range provides the index and a copy of the element at that index.
What is the difference between continue and break in Go?
Continue stops the current iteration and continues to the next one. Break stops the current iteration and exits the loop.
