V
Vel·ToolKit
Simple · Fast · Ready to use
EN
Chapter 4 of 20

Control Flow

if / for / switch / defer

if Statements

Conditions don't need parentheses; you can declare a local variable inside the if.

package main

import (
    "fmt"
    "strconv"
)

func main() {
    s := "42"
    if v, err := strconv.Atoi(s); err == nil {
        fmt.Println("num:", v)
    } else {
        fmt.Println("not a number")
    }
}

for Loops

Go has only for, but it expresses four forms: the C-style three-part loop, while, an infinite loop, and range.

package main

import "fmt"

func main() {
    // three-part form
    for i := 0; i < 3; i++ {
        fmt.Println(i)
    }

    // while style
    n := 3
    for n > 0 {
        n--
    }
    fmt.Println("n=", n)

    // infinite loop + break
    i := 0
    for {
        if i >= 2 {
            break
        }
        i++
    }

    // range: index + value
    for i, v := range []int{10, 20, 30} {
        fmt.Println(i, v)
    }
}

switch

No fall-through by default; any expression can serve as a case, and fallthrough opts into explicit fall-through. The expression-less form can replace an if-else chain.

package main

import (
    "fmt"
    "time"
)

func main() {
    switch day := time.Now().Weekday(); day {
    case time.Saturday, time.Sunday:
        fmt.Println("weekend")
    default:
        fmt.Println("workday")
    }

    // expression-less form: replaces an if-else chain
    score := 85
    grade := "F"
    switch {
    case score >= 90:
        grade = "A"
    case score >= 60:
        grade = "B"
    }
    fmt.Println("grade:", grade)
}

defer

defer postpones a statement until just before the enclosing function returns, in last-in-first-out order. Commonly used to release resources.

package main

import (
    "fmt"
    "os"
)

func main() {
    if err := readFile("/etc/hostname"); err != nil {
        fmt.Println("err:", err)
    }
}

func readFile(path string) error {
    f, err := os.Open(path)
    if err != nil {
        return err
    }
    defer f.Close() // called automatically before the function returns

    info, err := f.Stat()
    if err != nil {
        return err
    }
    fmt.Println(info.Name(), info.Size())
    return nil
}

break / continue / goto

Labeled break/continue can jump out of nested loops; goto still exists but is rarely used.