Skip to content

Control Flow

Scope: if, for (Go's only loop), and switch. All examples were compiled and run.

if: no parentheses

if age >= 18 {
    fmt.Println("adult")
} else {
    fmt.Println("minor")
}

No parentheses around the condition — gofmt would remove them. Braces are mandatory, even for one line.

Go lets you run a short statement before the condition:

if n := len(name); n > 5 {
    fmt.Println("long name:", n)
}
// n doesn't exist out here

This keeps temporary variables scoped to where they're used.

for: the only loop

Go has one looping keyword: for. It covers everything.

Classic counted loop:

for i := 0; i < 5; i++ {
    fmt.Println(i)
}

While-style loop (condition only):

n := 1
for n < 100 {
    n *= 2
}

Forever (break out yourself):

for {
    fmt.Println("again")
    break  // remove this and it never stops
}

Over a collection (range):

nums := []int{10, 20, 30}
for i, v := range nums {
    fmt.Printf("index %d = %d\n", i, v)
}

range gives you index and value. Don't need the index? The blank identifier _ throws it away:

for _, v := range nums {
    fmt.Println(v)
}

Unused variables are a compile error in Go, so _ isn't just style — it's required when you skip a value.

switch: cleaner than if-else chains

day := "Sat"
switch day {
case "Sat", "Sun":
    fmt.Println("weekend")
case "Mon":
    fmt.Println("back to work")
default:
    fmt.Println("weekday")
}

Two Go-specific notes:

  • No break needed. Cases don't fall through — each case ends automatically. (The rare explicit fallthrough keyword opts back in.)
  • Cases can list multiple values (case "Sat", "Sun":).

switch can also switch on nothing, acting as a clean if-else:

score := 85
switch {
case score >= 90:
    fmt.Println("A")
case score >= 80:
    fmt.Println("B")
default:
    fmt.Println("keep practicing")
}

defer: run this when the function ends

f, err := os.Open("data.txt")
if err != nil {
    log.Fatal(err)
}
defer f.Close()  // runs when the surrounding function returns

defer schedules a call for when the current function exits — no matter how it exits. It's how Go cleans up files, locks, and connections without try/finally. You'll use it constantly once you start opening resources.

Check

  • [ ] You can write all four for forms from memory
  • [ ] You know why break isn't needed in switch cases
  • [ ] You can explain what defer does and when you'd use it

Next: Functions.