if, for and switch

Go · Essentials · 10 min

Go deliberately has only one loop and a very regular switch; knowing their forms covers almost all control flow.

if has no parentheses but always needs braces. It can start with a short statement whose variables are scoped to the if/else: if n, err := strconv.Atoi(s); err == nil { ... }. This keeps temporary variables out of the surrounding scope and is used constantly with errors.

for is Go's only loop, in several shapes:

  • for i := 0; i < 10; i++ { } — classic three-part loop.
  • for cond { } — a while loop; for { } loops forever.
  • for i, v := range items { } — iterate slices, arrays, strings, maps and channels. Use _ to ignore the index.
  • for i := range 10 { } — since Go 1.22 you can range over an integer: 0 to 9.

Since Go 1.22 each iteration gets a fresh copy of the loop variables, so closures and goroutines capturing i see the value of that iteration.

break and continue work as expected; label the outer loop (outer: for ... then break outer) to exit nested loops.

switch compares a value against cases top to bottom and runs the first match. There is no fall-through by default — no break needed. A case can list several values (case "sat", "sun":), and a switch with no expression acts as a clean if/else chain: switch { case x < 0: ... case x == 0: ... }. Use the fallthrough keyword in the rare case you want to continue into the next case.

Example

package main

import (
	"fmt"
	"strconv"
)

func main() {
	if n, err := strconv.Atoi("42"); err == nil {
		fmt.Println("parsed", n) // parsed 42
	}

	for i := range 3 {
		fmt.Print(i, " ") // 0 1 2
	}
	fmt.Println()

	for _, day := range []string{"mon", "sat"} {
		switch day {
		case "sat", "sun":
			fmt.Println(day, "weekend")
		default:
			fmt.Println(day, "weekday")
		}
	}
}

Remember

  • for covers classic, while, infinite and range loops
  • Use if x, err := f(); err != nil to scope temporaries
  • switch cases don't fall through; list several values per case

Watch out for

  • Writing break inside a switch inside a for loop expecting to leave the loop — it only leaves the switch; use a label.

Check yourself

  1. What does this print? `for i := range 4 { if i == 2 { continue }; fmt.Print(i) }`

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: go.dev/ref/spec#For_statements