← Back to Go Course | Chapter 3: Control Flow | Lesson 5 of 7

The goto Statement

goto lets your program jump straight to a labeled spot in the code, like skipping ahead to a bookmarked page instead of reading in order.

Basic goto Usage

A goto statement transfers control to a label elsewhere in the same function. The label is just an identifier followed by a colon, placed before the statement you want to jump to.

Example: Basic goto Usage

markup
package main

import "fmt"

func main() {
	i := 0
Loop:
	if i < 3 {
		fmt.Println("i =", i)
		i++
		goto Loop
	}
	fmt.Println("done")
}

Restrictions on goto

Go's compiler forbids a goto from jumping into the middle of a block or past a variable declaration it hasn't executed yet, which prevents many of the classic bugs and undefined states that made goto notorious in older languages like C.

Example: Restrictions on goto

markup
package main

import "fmt"

func main() {
	n := 5
	if n > 0 {
		goto Positive
	}
	fmt.Println("non-positive")
	return
Positive:
	fmt.Println("n is positive:", n)
}

Breaking Out of Nested Loops

One of the few places goto still appears in real Go code is jumping straight out of deeply nested loops when a labeled break would be awkward, though labeled break/continue (covered separately) is generally preferred.

Note: A labeled break is usually clearer than goto for this same purpose.

Example: Breaking Out of Nested Loops

markup
package main

import "fmt"

func main() {
	for i := 0; i < 3; i++ {
		for j := 0; j < 3; j++ {
			if i == 1 && j == 1 {
				goto Done
			}
			fmt.Println(i, j)
		}
	}
Done:
	fmt.Println("exited nested loops")
}
Common Mistakes
  1. Overusing goto to build complex control flow that would be far clearer as a loop or function, creating hard-to-follow 'spaghetti code'.
  2. Trying to jump into the middle of a block or over a variable declaration, which Go's compiler explicitly forbids.
  3. Using goto to simulate a loop when a plain for loop (or break/continue with a label) already does the job more idiomatically.
Chapter Summary
  • 'goto label' jumps execution directly to a labeled statement in the same function.
  • Go restricts goto so it cannot jump into a block or skip over a variable declaration, preventing many classic goto bugs.
  • goto is rarely used in idiomatic Go, mostly reserved for breaking out of deeply nested loops or generated code.
  • Labeled break/continue usually solve the same problem more clearly than goto.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.