Introduction
When loops are nested, a plain break or continue only affects the innermost loop, which is not always what you want. Go solves this with labeled statements: you attach a label to an outer loop, then use break Label or continue Label from inside a nested loop to control that specific outer loop directly. Go also provides a goto statement for unconditional jumps within a function, though it is rarely used and comes with strict restrictions.
Cricket analogy: A labeled break only affecting the innermost loop by default is like a fielder stopping just their own chase for the ball while the rest of the field keeps playing on, unless the captain specifically calls off the whole play.
Syntax
Outer:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if j == 1 {
continue Outer
}
if i == 2 {
break Outer
}
}
}
// goto
i := 0
Loop:
if i < 3 {
i++
goto Loop
}Explanation
A label is an identifier followed by a colon placed immediately before a for, switch, or select statement. Using break LabelName exits the labeled statement entirely, while continue LabelName skips to the next iteration of the labeled loop, even from several levels of nesting deep. This is the idiomatic way to break out of nested loops in Go, since Go has no multi-level break by number like some other languages. The goto statement jumps to a label anywhere in the same function, but Go enforces restrictions: it cannot jump into the scope of a variable declaration, and it cannot jump into a block from outside it. Because of these restrictions and readability concerns, goto is uncommon in idiomatic Go code, though it occasionally appears in generated code or specific error-handling patterns.
Cricket analogy: break LabelName exiting a labeled loop entirely is like a captain calling off the whole innings from the boundary rope, ending every over in progress at once rather than just the current ball.
Example
package main
import "fmt"
func main() {
Search:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if i*j > 2 {
fmt.Println("found at", i, j)
break Search
}
fmt.Println("checking", i, j)
}
}
count := 0
Retry:
if count < 3 {
fmt.Println("attempt", count)
count++
goto Retry
}
}Output
checking 0 0
checking 0 1
checking 0 2
checking 1 0
checking 1 1
checking 1 2
found at 2 2
attempt 0
attempt 1
attempt 2Key Takeaways
- A label precedes a for, switch, or select statement, ending with a colon.
- break Label exits the labeled statement completely, from any nesting depth.
- continue Label resumes the next iteration of the labeled loop.
- goto jumps to a label within the same function, subject to strict scope rules.
- goto cannot jump into a block or over a variable declaration.
- Labeled break/continue is the idiomatic way to control nested loops in Go.
Practice what you learned
1. What does a plain (unlabeled) break statement affect inside nested loops?
2. Where must a label be placed in Go?
3. What does 'continue Outer' do when Outer labels the enclosing loop?
4. Which of these is a restriction on Go's goto statement?
5. Why is goto rarely used in idiomatic Go code?
Was this page helpful?
You May Also Like
for Loops in Go
Master Go's single looping construct, which covers classic for, while-style, infinite, and range-based loops.
switch Statements in Go
Understand Go's switch statement, including implicit break, fallthrough, tagless switches, and type switches.
The select Statement in Go
The select statement lets a goroutine wait on multiple channel operations at once, proceeding with whichever is ready first.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics