What break does
A for loop normally runs until its condition fails or, for range, until it runs out of elements. The break statement ends the loop sooner. When Go reaches break, it leaves the innermost enclosing for immediately, and execution continues with the first statement after the loop. No further condition is checked and no further iteration starts.
Use it when the rest of the work is pointless once something has happened: you found the item you were looking for, you hit a stop value, or a limit is reached.
Breaking a range loop
fruits := []string{"kivi", "orange", "banana", "apple", "pear"}
for _, fruit := range fruits {
fmt.Println(fruit)
if fruit == "banana" {
break
}
}
The output is:
kivi
orange
banana
On the first two passes the if is false, so the loop moves on. On the third pass fruit is "banana", the print has already happened, and break ends the loop. apple and pear are never visited.
The blank identifier _ discards the index. Go refuses to compile a program with an unused variable, so a range loop that needs only the value must name the index _.
Breaking an index loop
break works the same way in the three-part form:
for i := 0; i < len(fruits); i++ {
fmt.Printf("Index %d: %s\n", i, fruits[i])
if fruits[i] == "banana" {
break
}
}
Index 0: kivi
Index 1: orange
Index 2: banana
The position of the check matters. Here it comes after the print, so the matching element is printed before the loop stops. Moving the if above the print would stop the loop without printing banana.
Gotchas in Go
- Only the innermost loop ends. In nested loops,
breakleaves the inner one and the outer loop carries on. To leave both, put a label before the outerforand writebreak outer. With a labelouter:in front of the outer loop of a 3 by 3 pair of loops,break outerati == 1 && j == 1prints the pairs (0,0), (0,1), (0,2) and (1,0), then stops everything. breakinside aswitchleaves only the switch. In many languages aswitchneedsbreakat the end of each case. In Go it doesn't, because cases don't fall through. If you writebreakinside aswitchthat sits in a loop, it ends theswitch, not the loop, and the loop continues. Use a label to break the loop from there.- No match means no break. If the condition never becomes true, the loop simply runs to its normal end. A loop that looks for
"none"in the fruits above would print all five fruits. - The loop variable after
break. A variable declared in theforheader, likeiabove, exists only inside the loop. To use the index afterwards, declare it before the loop and writefor i = 0; ....
The exercise: print the finished lessons
The task is to print every lesson a student finished. The slice lessons holds the course in order, and lastFinishedLesson names the last lesson the student completed. Everything up to and including that lesson counts as finished, so the loop must stop right after printing it.
- Loop over the lessons.
for _, lesson := range lessonsvisits each name in order, with_dropping the index. - Print each one.
"Finished " + lessonjoins the two strings, andfmt.Printlnprints the result. - Stop after the last finished lesson. Compare
lessonwithlastFinishedLessonandbreakon a match. The check sits after the print so the last finished lesson is still printed.
lessons := []string{"variables", "conditionals", "arrays", "functions", "loops"}
lastFinishedLesson := "functions"
for _, lesson := range lessons {
fmt.Println("Finished " + lesson)
if lesson == lastFinishedLesson {
break
}
}
This prints:
Finished variables
Finished conditionals
Finished arrays
Finished functions
The lesson "loops" is never reached. Comparing strings with == is fine in Go: it compares the text, not an address.
Key takeaways
breakends the innermost enclosingforat once, and the program continues after the loop.- Where you put the check decides whether the current element is processed before the loop stops.
- Inside a nested loop, use a label such as
break outerto leave the outer loop. - Inside a
switch, a barebreakleaves only theswitch.