Loops in Go
By Syncfusion®, Inc. · Last updated
Repeat work in Go with the for loop in its three forms, walk through arrays, slices, strings, maps and channels with range, and control loops with break, continue, labels and goto.
What Are Loops?
Loop = code that repeats while a condition is true.
Iteration = one trip through the loop.
Without a loop, printing roll numbers 1 to 40 needs 40 lines. With a loop, it needs 3.
Simple lesson: a loop repeats work so you do not have to write the same line again and again.
A Real-World Example
At morning assembly, the teacher takes attendance.
- She starts at roll number 1.
- She calls one name and marks it.
- She moves to the next roll number.
- She stops after the last student.
That is a loop:
- Start at 1.
- Check if there are students left.
- Do the work: call the name.
- Move to the next number.
Go has only one loop keyword: for.
- It can count, like a
forloop in other languages. - It can wait for a condition, like a
whileloop. - It can run forever.
- With
range, it can walk through lists, text, maps and channels.
What You Will Learn
In this lesson, you will learn:
- Why loops are used.
- The three forms of
for: counting, condition-only and infinite. - How
rangewalks through arrays, slices, strings, maps and channels. - How to stop or skip with
breakandcontinue, and how labels work. - How to put one loop inside another.
Loop Fundamentals
Why Loops Are Used
- Repeat a task a fixed number of times, like printing a table.
- Go through every item in a list, like all students' marks.
- Keep trying until something happens, like a correct password.
- Add things up, like a total or a count.
Without and with a loop
package main
import "fmt"
func main() {
fmt.Println("Roll 1")
fmt.Println("Roll 2")
fmt.Println("Roll 3")
for roll := 1; roll <= 3; roll++ {
fmt.Println("Roll", roll)
}
}
Roll 1
Roll 2
Roll 3
Roll 1
Roll 2
Roll 3
- Both halves print the same thing.
- Change
3to40in the loop, and it prints 40 lines. The first half would need 37 more lines.
Simple lesson: use a loop when the same work repeats.
The for Loop
Traditional for Loop
for init; condition; post {
// body
}
- init runs once, before the first trip.
- condition is checked before every trip. The loop stops when it is false.
- post runs after every trip, usually
i++. - body is the work to repeat.
Move the slider, then step through the loop.
Watch the order:
- init happens once.
- Then it is always check, body, post, again and again.
- The last check is false, and the loop ends.
The 7 times table
package main
import "fmt"
func main() {
for i := 1; i <= 5; i++ {
fmt.Println("7 x", i, "=", 7*i)
}
}
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
ilives only inside the loop.- You can count down too:
for i := 10; i >= 1; i--.
Condition-Only Loop
Leave out init and post. Only the condition stays.
This is Go's version of a while loop.
Save money until you can buy the book
- Use this form when you do not know how many trips you need.
- Something inside the loop must change the condition, or it never stops.
Infinite Loop
Infinite loop = for { }, a loop with no condition. It runs until something stops it.
An infinite loop with a way out
package main
import "fmt"
func main() {
guesses := []int{3, 8, 7}
secret := 7
tries := 0
for {
guess := guesses[tries]
tries++
if guess == secret {
fmt.Println("Found it in", tries, "tries")
break
}
fmt.Println(guess, "is wrong")
}
}
3 is wrong
8 is wrong
Found it in 3 tries
breakjumps out of the loop.- Servers often run an infinite loop, waiting for requests.
[]int{3, 8, 7}is a list of numbers called a slice. You will learn it in Slices.
A loop whose condition never becomes false runs forever.
In this lab, a program that runs too long is stopped after a few seconds. On your computer, press Ctrl + C in the terminal to stop it.
Simple lesson: for can count (init; condition; post), wait (condition only) or run forever (for { }).
The range Loop
range = walk through every item in a collection, one at a time.
Each trip gives you the index (position) and the value.
What range gives you
range with Arrays
range over an array
package main
import "fmt"
func main() {
days := [3]string{"Mon", "Tue", "Wed"}
for i, day := range days {
fmt.Println(i, day)
}
}
0 Mon
1 Tue
2 Wed
- Positions start at
0, not1. - You will learn arrays in Arrays.
range with Slices
Total and average of marks
package main
import "fmt"
func main() {
marks := []int{91, 78, 85, 66}
total := 0
for _, m := range marks {
total += m
}
fmt.Println("Total:", total)
fmt.Println("Average:", float64(total)/float64(len(marks)))
}
Total: 320
Average: 80
_throws away the index, because we only need the marks.- Write
for i := range marksif you need only the index.
range with Strings
range over a string
package main
import "fmt"
func main() {
for i, r := range "Hi!" {
fmt.Println(i, string(r))
}
}
0 H
1 i
2 !
- Each
ris a rune: one character. - For Hindi or emoji,
ijumps by more than 1, because those characters use several bytes. See Strings.
range with Maps
Map = a set of key and value pairs, like a phone book. You will learn it in Maps.
Add up a map's values
package main
import "fmt"
func main() {
books := map[string]int{"Asha": 3, "Ravi": 5, "Meena": 2}
total := 0
for _, count := range books {
total += count
}
fmt.Println("Books borrowed:", total)
}
Books borrowed: 10
- Go walks through a map in a different order each time.
- So do not rely on the order when you print a map in a loop.
- Adding up gives the same answer in any order.
range with Channels
Channel = a pipe that one part of a program uses to send values to another. You will learn it in Channels.
range over a channel
package main
import "fmt"
func main() {
queue := make(chan string, 3)
queue <- "Asha"
queue <- "Ravi"
close(queue)
for name := range queue {
fmt.Println("Next:", name)
}
}
Next: Asha
Next: Ravi
rangeover a channel takes values until the channel is closed.
Simple lesson: range walks through each item and gives you its position and value.
Loop Control Statements
break
break = leave the loop right now.
Stop at the first failing mark
package main
import "fmt"
func main() {
marks := []int{78, 92, 31, 88}
for i, m := range marks {
if m < 35 {
fmt.Println("First fail at position", i)
break
}
fmt.Println("OK:", m)
}
}
OK: 78
OK: 92
First fail at position 2
continue
continue = skip the rest of this trip and start the next one.
Print only the even roll numbers
package main
import "fmt"
func main() {
for roll := 1; roll <= 6; roll++ {
if roll%2 != 0 {
continue
}
fmt.Println("Roll", roll)
}
}
Roll 2
Roll 4
Roll 6
- For odd numbers,
continueskips the print. - The post statement
roll++still runs.
Labels
Label = a name for a loop, so break or continue can reach an outer loop.
break out of two loops at once
package main
import "fmt"
func main() {
classes := [][]string{{"Asha", "Ravi"}, {"Meena", "Kabir"}}
target := "Meena"
search:
for c, class := range classes {
for _, name := range class {
if name == target {
fmt.Println("Found", name, "in class", c)
break search
}
}
}
fmt.Println("Search done")
}
Found Meena in class 1
Search done
search:names the outer loop.- A plain
breakwould leave only the inner loop. break searchleaves both.
goto
goto = jump to a label somewhere else in the same function.
goto (rarely used)
package main
import "fmt"
func main() {
n := 1
again:
fmt.Println("Try", n)
n++
if n <= 3 {
goto again
}
}
Try 1
Try 2
Try 3
gotoexists, but it makes code hard to follow.- Almost always, a
forloop is clearer. Prefer it.
Easy way to remember
break= leave the loop.continue= skip to the next trip.break label= leave an outer loop.goto= avoid it.
Simple lesson: break stops the loop, continue skips one trip, and labels let you reach an outer loop.
Nested Loops
Nested loop = a loop inside another loop.
For every trip of the outer loop, the inner loop runs all its trips.
A small multiplication grid
Practical Examples
A star triangle
package main
import "fmt"
func main() {
for row := 1; row <= 4; row++ {
for star := 1; star <= row; star++ {
fmt.Print("*")
}
fmt.Println()
}
}
*
**
***
****
- Row 1 prints 1 star, row 2 prints 2 stars, and so on.
- The inner loop uses the outer loop's
rowas its limit.
Class toppers
package main
import "fmt"
func main() {
names := []string{"8A", "8B"}
marks := [][]int{{78, 95, 88}, {91, 67, 84}}
for c, list := range marks {
best := 0
for _, m := range list {
if m > best {
best = m
}
}
fmt.Println(names[c], "top mark:", best)
}
}
8A top mark: 95
8B top mark: 91
- The outer loop picks a class.
- The inner loop finds the biggest mark in that class.
Simple lesson: in a nested loop, the inner loop finishes all its trips for each trip of the outer loop.
TL;DR
- Loop = repeat code. Go has only
for. Traditional =
for i := 0; i < n; i++ { }- init once, then check, body, post.
- Condition-only =
for x < 100 { }. Go's "while". - Infinite =
for { }. Leave withbreak. range =
for i, v := range collection { }- arrays, slices, strings (runes), maps (random order), channels, integers.
- break = leave. continue = next trip. label = reach an outer loop. goto = avoid.
- Nested loop = the inner loop runs fully for each outer trip.
Common mistakes
| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
for (i := 0; i < 5; i++) | Parentheses are needed | No parentheses in Go | A syntax error. |
while x < 5 { } | Go has while | Use for x < 5 { } | undefined: while |
| Forgetting to change the condition | The loop stops by itself | Something must change it | The loop never ends. |
i <= len(list) | The last index is len | The last index is len - 1 | index out of range panic. |
| Printing a map in a loop and expecting order | Maps keep insertion order | Map order changes each run | Output order changes. |
break in a nested loop to stop both | break leaves all loops | It leaves only the inner loop | The outer loop keeps going. |
for i, v := range marks with i unused | Unused loop variables are fine | Use _ for the index | declared and not used: i |
Check Yourself
Exercises
What to Remember
- Go has one loop keyword:
for. for i := 0; i < n; i++counts.for condwaits.for { }runs forever.rangegives the position and the value of each item.- Map order changes every run.
breakleaves,continueskips, labels reach outer loops. Avoidgoto.- The inner loop runs fully for every trip of the outer loop.
Next: Functions. You will learn how to name a group of steps and reuse it with different values.